Metabench support and tests added

This commit is contained in:
Mateusz Pusz
2019-05-17 22:41:46 +02:00
parent a63b5ab111
commit 7bebf6e1e0
14 changed files with 1334 additions and 12 deletions

View File

@@ -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)

View 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)

View 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()
{
}

View 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

View 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()
{
}

View 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

View 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
)