1 //  (C) Copyright John Maddock 2015.
2 //  Use, modification and distribution are subject to the
3 //  Boost Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef BOOST_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP
7 #define BOOST_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP
8 
9 #include <boost/config.hpp>
10 #include <boost/detail/workaround.hpp>
11 
12 #if (BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
13    || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
14    || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) \
15    || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \
16    || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(810)) )
17 
18 
19 namespace boost{
20    namespace mpl
21    {
22       template <bool B> struct bool_;
23       template <class I, I val> struct integral_c;
24       struct integral_c_tag;
25    }
26 }
27 
28 #else
29 
30 namespace mpl_{
31 
32    template <bool B> struct bool_;
33    template <class I, I val> struct integral_c;
34    struct integral_c_tag;
35 }
36 
37 namespace boost
38 {
39    namespace mpl
40    {
41       using ::mpl_::bool_;
42       using ::mpl_::integral_c;
43       using ::mpl_::integral_c_tag;
44    }
45 }
46 
47 #endif
48 
49 namespace boost{
50 
51    template <class T, T val>
52    struct integral_constant
53    {
54       typedef mpl::integral_c_tag tag;
55       typedef T value_type;
56       typedef integral_constant<T, val> type;
57       static const T value = val;
58       //
59       // This helper function is just to disable type-punning
60       // warnings from GCC:
61       //
62       template <class U>
dereferenceboost::integral_constant63       static U& dereference(U* p) { return *p; }
64 
operator const mpl::integral_c<T,val>&boost::integral_constant65       operator const mpl::integral_c<T, val>& ()const
66       {
67          static const char data[sizeof(long)] = { 0 };
68          return dereference(reinterpret_cast<const mpl::integral_c<T, val>*>(&data));
69       }
operator Tboost::integral_constant70       BOOST_CONSTEXPR operator T()const { return val; }
71    };
72 
73    template <class T, T val>
74    T const integral_constant<T, val>::value;
75 
76    template <bool val>
77    struct integral_constant<bool, val>
78    {
79       typedef mpl::integral_c_tag tag;
80       typedef bool value_type;
81       typedef integral_constant<bool, val> type;
82       static const bool value = val;
83       //
84       // This helper function is just to disable type-punning
85       // warnings from GCC:
86       //
87       template <class T>
dereferenceboost::integral_constant88       static T& dereference(T* p) { return *p; }
89 
operator const mpl::bool_<val>&boost::integral_constant90       operator const mpl::bool_<val>& ()const
91       {
92          static const char data = 0;
93          return dereference(reinterpret_cast<const mpl::bool_<val>*>(&data));
94       }
operator boolboost::integral_constant95       BOOST_CONSTEXPR operator bool()const { return val; }
96    };
97 
98    template <bool val>
99    bool const integral_constant<bool, val>::value;
100 
101    typedef integral_constant<bool, true> true_type;
102    typedef integral_constant<bool, false> false_type;
103 
104 }
105 
106 #endif
107