Skip to content

Commit

Permalink
Metabench support and tests added
Browse files Browse the repository at this point in the history
  • Loading branch information
mpusz committed May 17, 2019
1 parent a63b5ab commit 7bebf6e
Show file tree
Hide file tree
Showing 14 changed files with 1,334 additions and 12 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ cmake_minimum_required(VERSION 3.8)
project(units)

# set path to custom cmake modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/cmake")

# include common tools and workarounds
Expand Down
1,005 changes: 1,005 additions & 0 deletions cmake/metabench.cmake

Large diffs are not rendered by default.

14 changes: 2 additions & 12 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 52 additions & 0 deletions test/metabench/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 20 additions & 0 deletions test/metabench/ratio/ratio_type_constexpr.cpp.erb
Original file line number Diff line number Diff line change
@@ -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 changes: 116 additions & 0 deletions test/metabench/ratio/ratio_type_constexpr.h
Original file line number Diff line number Diff line change
@@ -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 changes: 20 additions & 0 deletions test/metabench/ratio/std_ratio.cpp.erb
Original file line number Diff line number Diff line change
@@ -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 changes: 84 additions & 0 deletions test/metabench/ratio/std_ratio.h
Original file line number Diff line number Diff line change
@@ -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 changes: 34 additions & 0 deletions test/unit_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit 7bebf6e

Please sign in to comment.