• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Louis Dionne 2013-2017
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4 
5 #ifndef TEST_SUPPORT_CNUMERIC_HPP
6 #define TEST_SUPPORT_CNUMERIC_HPP
7 
8 #include <boost/hana/concept/integral_constant.hpp>
9 #include <boost/hana/core/when.hpp>
10 #include <boost/hana/fwd/core/to.hpp>
11 #include <boost/hana/fwd/equal.hpp>
12 #include <boost/hana/fwd/less.hpp>
13 
14 
15 template <typename T>
16 struct CNumeric { using value_type = T; };
17 
18 template <typename T, T v>
19 struct cnumeric_t {
20     static constexpr T value = v;
21     using hana_tag = CNumeric<T>;
operator Tcnumeric_t22     constexpr operator T() const { return value; }
23 };
24 
25 template <typename T, T v>
26 constexpr cnumeric_t<T, v> cnumeric{};
27 
28 template <typename T, T v>
make_cnumeric()29 constexpr cnumeric_t<T, v> make_cnumeric() { return {}; }
30 
31 namespace boost { namespace hana {
32     // Constant and IntegralConstant
33     template <typename T>
34     struct IntegralConstant<CNumeric<T>> {
35         static constexpr bool value = true;
36     };
37 
38     template <typename T, typename C>
39     struct to_impl<CNumeric<T>, C, when<
40         hana::IntegralConstant<C>::value
41     >>
42         : embedding<is_embedded<typename C::value_type, T>::value>
43     {
44         template <typename N>
applyboost::hana::to_impl45         static constexpr auto apply(N const&)
46         { return cnumeric<T, N::value>; }
47     };
48 
49     // Comparable
50     template <typename T, typename U>
51     struct equal_impl<CNumeric<T>, CNumeric<U>> {
52         template <typename X, typename Y>
applyboost::hana::equal_impl53         static constexpr auto apply(X const&, Y const&)
54         { return cnumeric<bool, X::value == Y::value>; }
55     };
56 
57     // Orderable
58     template <typename T, typename U>
59     struct less_impl<CNumeric<T>, CNumeric<U>> {
60         template <typename X, typename Y>
applyboost::hana::less_impl61         static constexpr auto apply(X const&, Y const&)
62         { return cnumeric<bool, (X::value < Y::value)>; }
63     };
64 }} // end namespace boost::hana
65 
66 #endif // !TEST_SUPPORT_CNUMERIC_HPP
67