summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/test/_include/support/numeric.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hana/test/_include/support/numeric.hpp')
-rw-r--r--src/boost/libs/hana/test/_include/support/numeric.hpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/boost/libs/hana/test/_include/support/numeric.hpp b/src/boost/libs/hana/test/_include/support/numeric.hpp
new file mode 100644
index 000000000..2aebe7664
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/numeric.hpp
@@ -0,0 +1,175 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef TEST_SUPPORT_NUMERIC_HPP
+#define TEST_SUPPORT_NUMERIC_HPP
+
+#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/eval.hpp>
+#include <boost/hana/fwd/div.hpp>
+#include <boost/hana/fwd/equal.hpp>
+#include <boost/hana/fwd/eval_if.hpp>
+#include <boost/hana/fwd/less.hpp>
+#include <boost/hana/fwd/minus.hpp>
+#include <boost/hana/fwd/mod.hpp>
+#include <boost/hana/fwd/mult.hpp>
+#include <boost/hana/fwd/negate.hpp>
+#include <boost/hana/fwd/not.hpp>
+#include <boost/hana/fwd/one.hpp>
+#include <boost/hana/fwd/plus.hpp>
+#include <boost/hana/fwd/while.hpp>
+#include <boost/hana/fwd/zero.hpp>
+
+
+struct numeric_type {
+ constexpr explicit numeric_type(int v) : value(v) { }
+ int value;
+ constexpr operator int() const { return value; }
+};
+
+using Numeric = boost::hana::tag_of_t<numeric_type>;
+
+struct numeric_t {
+ constexpr numeric_type operator()(int x) const {
+ return numeric_type{x};
+ }
+};
+constexpr numeric_t numeric{};
+
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct equal_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value == y.value); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Orderable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct less_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y) {
+ // Workaround a _weird_ GCC bug:
+ // error: parse error in template argument list
+ // bool cmp = (x.value < y.value);
+ // ^
+ int xv = x.value, yv = y.value;
+ return numeric(xv < yv);
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Logical
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct eval_if_impl<Numeric> {
+ template <typename C, typename T, typename E>
+ static constexpr auto apply(C const& c, T&& t, E&& e) {
+ return c.value ? hana::eval(static_cast<T&&>(t))
+ : hana::eval(static_cast<E&&>(e));
+ }
+ };
+
+ template <>
+ struct not_impl<Numeric> {
+ template <typename X>
+ static constexpr auto apply(X x)
+ { return numeric(!x.value); }
+ };
+
+ template <>
+ struct while_impl<Numeric> {
+ template <typename Pred, typename State, typename F>
+ static constexpr auto apply(Pred pred, State state, F f)
+ -> decltype(true ? f(state) : state)
+ {
+ if (pred(state))
+ return hana::while_(pred, f(state), f);
+ else
+ return state;
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Monoid
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct plus_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value + y.value); }
+ };
+
+ template <>
+ struct zero_impl<Numeric> {
+ static constexpr auto apply()
+ { return numeric(0); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Group
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_GROUP_NEGATE_MCD
+ // BOOST_HANA_TEST_GROUP_MINUS_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+#if defined(BOOST_HANA_TEST_GROUP_NEGATE_MCD)
+ template <>
+ struct negate_impl<Numeric> {
+ template <typename X>
+ static constexpr auto apply(X x)
+ { return numeric(-x.value); }
+ };
+#else
+ template <>
+ struct minus_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value - y.value); }
+ };
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Ring
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct mult_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value * y.value); }
+ };
+
+ template <>
+ struct one_impl<Numeric> {
+ static constexpr auto apply()
+ { return numeric(1); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // EuclideanRing
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct div_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value / y.value); }
+ };
+
+ template <>
+ struct mod_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value % y.value); }
+ };
+}} // end namespace boost::hana
+
+#endif //! TEST_SUPPORT_NUMERIC_HPP