1 | /* boost random/traits.hpp header file |
2 | * |
3 | * Copyright John Maddock 2015 |
4 | * Distributed under the Boost Software License, Version 1.0. (See |
5 | * accompanying file LICENSE_1_0.txt or copy at |
6 | * http://www.boost.org/LICENSE_1_0.txt) |
7 | * |
8 | * See http://www.boost.org for most recent version including documentation. |
9 | * |
10 | * These traits classes serve two purposes: they are designed to mostly |
11 | * work out of the box for multiprecision types (ie number types that are |
12 | * C++ class types and not integers or floats from type-traits point of view), |
13 | * they are also a potential point of specialization for user-defined |
14 | * number types. |
15 | * |
16 | * $Id$ |
17 | */ |
18 | |
19 | #ifndef BOOST_RANDOM_TRAITS_HPP |
20 | #define BOOST_RANDOM_TRAITS_HPP |
21 | |
22 | #include <boost/type_traits/is_signed.hpp> |
23 | #include <boost/type_traits/is_integral.hpp> |
24 | #include <boost/type_traits/make_unsigned.hpp> |
25 | #include <boost/mpl/bool.hpp> |
26 | #include <limits> |
27 | |
28 | namespace boost { |
29 | namespace random { |
30 | namespace traits { |
31 | // \cond show_private |
32 | template <class T, bool intrinsic> |
33 | struct make_unsigned_imp |
34 | { |
35 | typedef typename boost::make_unsigned<T>::type type; |
36 | }; |
37 | template <class T> |
38 | struct make_unsigned_imp<T, false> |
39 | { |
40 | BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized); |
41 | BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_signed == false); |
42 | BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_integer == true); |
43 | typedef T type; |
44 | }; |
45 | // \endcond |
46 | /** \brief Converts the argument type T to an unsigned type. |
47 | * |
48 | * This trait has a single member `type` which is the unsigned type corresponding to T. |
49 | * Note that |
50 | * if T is signed, then member `type` *should define a type with one more bit precision than T*. For built-in |
51 | * types this trait defaults to `boost::make_unsigned<T>::type`. For user defined types it simply asserts that |
52 | * the argument type T is an unsigned integer (using std::numeric_limits). |
53 | * User defined specializations may be provided for other cases. |
54 | */ |
55 | template <class T> |
56 | struct make_unsigned |
57 | // \cond show_private |
58 | : public make_unsigned_imp < T, boost::is_integral<T>::value > |
59 | // \endcond |
60 | {}; |
61 | // \cond show_private |
62 | template <class T, bool intrinsic> |
63 | struct make_unsigned_or_unbounded_imp |
64 | { |
65 | typedef typename boost::make_unsigned<T>::type type; |
66 | }; |
67 | template <class T> |
68 | struct make_unsigned_or_unbounded_imp<T, false> |
69 | { |
70 | BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized); |
71 | BOOST_STATIC_ASSERT((std::numeric_limits<T>::is_signed == false) || (std::numeric_limits<T>::is_bounded == false)); |
72 | BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_integer == true); |
73 | typedef T type; |
74 | }; |
75 | // \endcond |
76 | /** \brief Converts the argument type T to either an unsigned type or an unbounded integer type. |
77 | * |
78 | * This trait has a single member `type` which is either the unsigned type corresponding to T or an unbounded |
79 | * integer type. This trait is used to generate types suitable for the calculation of a range: as a result |
80 | * if T is signed, then member `type` *should define a type with one more bit precision than T*. For built-in |
81 | * types this trait defaults to `boost::make_unsigned<T>::type`. For user defined types it simply asserts that |
82 | * the argument type T is either an unbounded integer, or an unsigned one (using std::numeric_limits). |
83 | * User defined specializations may be provided for other cases. |
84 | */ |
85 | template <class T> |
86 | struct make_unsigned_or_unbounded |
87 | // \cond show_private |
88 | : public make_unsigned_or_unbounded_imp < T, boost::is_integral<T>::value > |
89 | // \endcond |
90 | {}; |
91 | /** \brief Traits class that indicates whether type T is an integer |
92 | */ |
93 | template <class T> |
94 | struct is_integral |
95 | : public mpl::bool_<boost::is_integral<T>::value || (std::numeric_limits<T>::is_integer)> |
96 | {}; |
97 | /** \brief Traits class that indicates whether type T is a signed integer |
98 | */ |
99 | template <class T> struct is_signed |
100 | : public mpl::bool_ < boost::is_signed<T>::value || (std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed)> |
101 | {}; |
102 | |
103 | } |
104 | } |
105 | } |
106 | |
107 | #endif |
108 | |