mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-01 03:14:29 +02:00
Metabench support and tests added
This commit is contained in:
@@ -20,15 +20,5 @@
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
# unit tests
|
||||
add_library(unit_tests
|
||||
test_dimension.cpp
|
||||
test_quantity.cpp
|
||||
test_tools.cpp
|
||||
test_type_list.cpp
|
||||
test_units.cpp
|
||||
)
|
||||
target_link_libraries(unit_tests
|
||||
PRIVATE
|
||||
mp::units
|
||||
)
|
||||
add_subdirectory(unit_test)
|
||||
add_subdirectory(metabench)
|
||||
|
52
test/metabench/CMakeLists.txt
Normal file
52
test/metabench/CMakeLists.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Mateusz Pusz
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
|
||||
function(add_metabench_test target name erb_path range)
|
||||
metabench_add_dataset(${target} "${erb_path}" "${range}" NAME "${name}")
|
||||
target_compile_features(${target} PUBLIC cxx_std_20)
|
||||
target_link_libraries(${target}
|
||||
PUBLIC
|
||||
CONAN_PKG::cmcstl2
|
||||
CONAN_PKG::gsl-lite
|
||||
)
|
||||
endfunction()
|
||||
|
||||
|
||||
include(metabench)
|
||||
if(NOT METABENCH_DIR)
|
||||
return()
|
||||
endif()
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_metabench_test(metabench.std_ratio "std::ratio" ratio/std_ratio.cpp.erb "[10, 50, 100, 500, 1000]")
|
||||
add_metabench_test(metabench.ratio_type_constexpr "ratio with constexpr" ratio/ratio_type_constexpr.cpp.erb "[10, 50, 100, 500, 1000]")
|
||||
metabench_add_chart(metabench.ratio
|
||||
TITLE "Ratio calculations on n types"
|
||||
SUBTITLE "(smaller is better)"
|
||||
DATASETS
|
||||
metabench.std_ratio
|
||||
metabench.ratio_type_constexpr
|
||||
)
|
||||
|
||||
add_custom_target(metabench DEPENDS metabench.ratio)
|
20
test/metabench/ratio/ratio_type_constexpr.cpp.erb
Normal file
20
test/metabench/ratio/ratio_type_constexpr.cpp.erb
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "ratio_type_constexpr.h"
|
||||
|
||||
#if defined(METABENCH)
|
||||
<% (1..n).each do |i| %>
|
||||
struct test<%= i %> {
|
||||
using r1 = units::ratio<<%= i %>, <%= n + 1 - i %>>;
|
||||
using r2 = units::ratio<<%= n + 1 - i %>, <%= i %>>;
|
||||
|
||||
using r3 = units::ratio_multiply<r1, r2>;
|
||||
using r4 = units::ratio_divide<r1, r2>;
|
||||
|
||||
using r5 = units::common_ratio_t<r1, r2>;
|
||||
};
|
||||
<% end %>
|
||||
#endif
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
116
test/metabench/ratio/ratio_type_constexpr.h
Normal file
116
test/metabench/ratio/ratio_type_constexpr.h
Normal file
@@ -0,0 +1,116 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include <numeric>
|
||||
#include <cstdint>
|
||||
|
||||
namespace units {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] constexpr T abs(T v) noexcept { return v < 0 ? -v : v; }
|
||||
|
||||
}
|
||||
|
||||
template<std::intmax_t Num, std::intmax_t Den = 1>
|
||||
struct ratio {
|
||||
static_assert(Den != 0, "zero denominator");
|
||||
static_assert(-INTMAX_MAX <= Num, "numerator too negative");
|
||||
static_assert(-INTMAX_MAX <= Den, "denominator too negative");
|
||||
|
||||
static constexpr std::intmax_t num = Num * (Den < 0 ? -1 : 1) / std::gcd(Num, Den);
|
||||
static constexpr std::intmax_t den = detail::abs(Den) / std::gcd(Num, Den);
|
||||
|
||||
using type = ratio<num, den>;
|
||||
};
|
||||
|
||||
// is_ratio
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_ratio = false;
|
||||
|
||||
template<intmax_t Num, intmax_t Den>
|
||||
inline constexpr bool is_ratio<ratio<Num, Den>> = true;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename T>
|
||||
concept bool Ratio = detail::is_ratio<T>;
|
||||
|
||||
// ratio_multiply
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename R1, typename R2>
|
||||
struct ratio_multiply {
|
||||
private:
|
||||
static constexpr intmax_t gcd1 = std::gcd(R1::num, R2::den);
|
||||
static constexpr intmax_t gcd2 = std::gcd(R2::num, R1::den);
|
||||
|
||||
public:
|
||||
using type = ratio<(R1::num / gcd1) * (R2::num / gcd2), (R1::den / gcd2) * (R2::den / gcd1)>;
|
||||
static constexpr intmax_t num = type::num;
|
||||
static constexpr intmax_t den = type::den;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename R1, typename R2>
|
||||
using ratio_multiply = typename detail::ratio_multiply<R1, R2>::type;
|
||||
|
||||
// ratio_divide
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename R1, typename R2>
|
||||
struct ratio_divide {
|
||||
static_assert(R2::num != 0, "division by 0");
|
||||
using type = ratio_multiply<R1, ratio<R2::den, R2::num>>;
|
||||
static constexpr intmax_t num = type::num;
|
||||
static constexpr intmax_t den = type::den;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename R1, typename R2>
|
||||
using ratio_divide = typename detail::ratio_divide<R1, R2>::type;
|
||||
|
||||
// common_ratio
|
||||
|
||||
// todo: simplified
|
||||
template<Ratio R1, Ratio R2>
|
||||
struct common_ratio {
|
||||
static constexpr intmax_t gcd_num = std::gcd(R1::num, R2::num);
|
||||
static constexpr intmax_t gcd_den = std::gcd(R1::den, R2::den);
|
||||
using type = ratio<gcd_num, (R1::den / gcd_den) * R2::den>;
|
||||
};
|
||||
|
||||
template<Ratio R1, Ratio R2>
|
||||
using common_ratio_t = typename common_ratio<R1, R2>::type;
|
||||
|
||||
} // namespace units
|
20
test/metabench/ratio/std_ratio.cpp.erb
Normal file
20
test/metabench/ratio/std_ratio.cpp.erb
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "std_ratio.h"
|
||||
|
||||
#if defined(METABENCH)
|
||||
<% (1..n).each do |i| %>
|
||||
struct test<%= i %> {
|
||||
using r1 = std::ratio<<%= i %>, <%= n + 1 - i %>>;
|
||||
using r2 = std::ratio<<%= n + 1 - i %>, <%= i %>>;
|
||||
|
||||
using r3 = std::ratio_multiply<r1, r2>;
|
||||
using r4 = std::ratio_divide<r1, r2>;
|
||||
|
||||
using r5 = units::common_ratio_t<r1, r2>;
|
||||
};
|
||||
<% end %>
|
||||
#endif
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
84
test/metabench/ratio/std_ratio.h
Normal file
84
test/metabench/ratio/std_ratio.h
Normal file
@@ -0,0 +1,84 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ratio>
|
||||
#include <type_traits>
|
||||
|
||||
namespace units {
|
||||
|
||||
// static_sign
|
||||
|
||||
template<std::intmax_t Pn>
|
||||
struct static_sign : std::integral_constant<std::intmax_t, (Pn < 0) ? -1 : 1> {
|
||||
};
|
||||
|
||||
// static_abs
|
||||
|
||||
template<std::intmax_t Pn>
|
||||
struct static_abs : std::integral_constant<std::intmax_t, Pn * static_sign<Pn>::value> {
|
||||
};
|
||||
|
||||
// static_gcd
|
||||
|
||||
template<std::intmax_t Pn, std::intmax_t Qn>
|
||||
struct static_gcd : static_gcd<Qn, (Pn % Qn)> {
|
||||
};
|
||||
|
||||
template<std::intmax_t Pn>
|
||||
struct static_gcd<Pn, 0> : std::integral_constant<std::intmax_t, static_abs<Pn>::value> {
|
||||
};
|
||||
|
||||
template<std::intmax_t Qn>
|
||||
struct static_gcd<0, Qn> : std::integral_constant<std::intmax_t, static_abs<Qn>::value> {
|
||||
};
|
||||
|
||||
// is_ratio
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_ratio = false;
|
||||
|
||||
template<intmax_t Num, intmax_t Den>
|
||||
inline constexpr bool is_ratio<std::ratio<Num, Den>> = true;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename T>
|
||||
concept bool Ratio = detail::is_ratio<T>;
|
||||
|
||||
// common_ratio
|
||||
|
||||
// todo: simplified
|
||||
template<Ratio R1, Ratio R2>
|
||||
struct common_ratio {
|
||||
using gcd_num = static_gcd<R1::num, R2::num>;
|
||||
using gcd_den = static_gcd<R1::den, R2::den>;
|
||||
using type = std::ratio<gcd_num::value, (R1::den / gcd_den::value) * R2::den>;
|
||||
};
|
||||
|
||||
template<Ratio R1, Ratio R2>
|
||||
using common_ratio_t = typename common_ratio<R1, R2>::type;
|
||||
|
||||
} // namespace units
|
34
test/unit_test/CMakeLists.txt
Normal file
34
test/unit_test/CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Mateusz Pusz
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
# unit tests
|
||||
add_library(unit_tests
|
||||
test_dimension.cpp
|
||||
test_quantity.cpp
|
||||
test_tools.cpp
|
||||
test_type_list.cpp
|
||||
test_units.cpp
|
||||
)
|
||||
target_link_libraries(unit_tests
|
||||
PRIVATE
|
||||
mp::units
|
||||
)
|
Reference in New Issue
Block a user