blob: 297ddf48e84726113d0d58de36cf828e5a050e34 [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001
2// (C) Copyright Tobias Schwinger
3//
4// Use modification and distribution are subject to the boost Software License,
5// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
6
7//------------------------------------------------------------------------------
8
9#ifndef BOOST_FT_DETAIL_CV_TRAITS_HPP_INCLUDED
10#define BOOST_FT_DETAIL_CV_TRAITS_HPP_INCLUDED
11
12#include <cstddef>
13#include <ndnboost/detail/workaround.hpp>
14
15#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
16 || BOOST_WORKAROUND(__BORLANDC__, <= 0x582)
17# include <ndnboost/type_traits/remove_cv.hpp>
18# include <ndnboost/type_traits/remove_pointer.hpp>
19# include <ndnboost/type_traits/remove_reference.hpp>
20#endif
21
22#include <ndnboost/function_types/property_tags.hpp>
23
24namespace ndnboost { namespace function_types { namespace detail {
25
26#if ! (defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
27 || BOOST_WORKAROUND(__BORLANDC__, <= 0x582))
28
29template<typename T> struct cv_traits
30{ typedef non_cv tag; typedef T type; };
31template<typename T> struct cv_traits<T &>
32{ typedef non_cv tag; typedef T type; };
33template<typename T> struct cv_traits<T *>
34{ typedef non_cv tag; typedef T type; };
35template<typename T> struct cv_traits<T * const>
36{ typedef non_cv tag; typedef T type; };
37template<typename T> struct cv_traits<T * volatile>
38{ typedef non_cv tag; typedef T type; };
39template<typename T> struct cv_traits<T * const volatile>
40{ typedef non_cv tag; typedef T type; };
41
42template<typename T> struct cv_traits<T const>
43{ typedef const_non_volatile tag; typedef T type; };
44template<typename T> struct cv_traits<T const &>
45{ typedef const_non_volatile tag; typedef T type; };
46template<typename T> struct cv_traits<T const *>
47{ typedef const_non_volatile tag; typedef T type; };
48template<typename T> struct cv_traits<T const * const>
49{ typedef const_non_volatile tag; typedef T type; };
50template<typename T> struct cv_traits<T const * volatile>
51{ typedef const_non_volatile tag; typedef T type; };
52template<typename T> struct cv_traits<T const * const volatile>
53{ typedef const_non_volatile tag; typedef T type; };
54
55template<typename T> struct cv_traits<T volatile>
56{ typedef volatile_non_const tag; typedef T type; };
57template<typename T> struct cv_traits<T volatile &>
58{ typedef volatile_non_const tag; typedef T type; };
59template<typename T> struct cv_traits<T volatile *>
60{ typedef volatile_non_const tag; typedef T type; };
61template<typename T> struct cv_traits<T volatile * const>
62{ typedef volatile_non_const tag; typedef T type; };
63template<typename T> struct cv_traits<T volatile * volatile>
64{ typedef volatile_non_const tag; typedef T type; };
65template<typename T> struct cv_traits<T volatile * const volatile>
66{ typedef volatile_non_const tag; typedef T type; };
67
68template<typename T> struct cv_traits<T const volatile>
69{ typedef cv_qualified tag; typedef T type; };
70template<typename T> struct cv_traits<T const volatile &>
71{ typedef cv_qualified tag; typedef T type; };
72template<typename T> struct cv_traits<T const volatile *>
73{ typedef cv_qualified tag; typedef T type; };
74template<typename T> struct cv_traits<T const volatile * const>
75{ typedef cv_qualified tag; typedef T type; };
76template<typename T> struct cv_traits<T const volatile * volatile>
77{ typedef cv_qualified tag; typedef T type; };
78template<typename T> struct cv_traits<T const volatile * const volatile>
79{ typedef cv_qualified tag; typedef T type; };
80
81#else
82template<std::size_t> struct cv_tag_impl;
83
84template<> struct cv_tag_impl<1> { typedef non_cv type;};
85template<> struct cv_tag_impl<2> { typedef const_non_volatile type; };
86template<> struct cv_tag_impl<3> { typedef volatile_non_const type; };
87template<> struct cv_tag_impl<4> { typedef cv_qualified type; };
88
89typedef char (& case_1)[1];
90typedef char (& case_2)[2];
91typedef char (& case_3)[3];
92typedef char (& case_4)[4];
93
94template<typename T> case_1 switch_cv(T *);
95template<typename T> case_2 switch_cv(T const *);
96template<typename T> case_3 switch_cv(T volatile *);
97template<typename T> case_4 switch_cv(T const volatile *);
98
99template<typename T> T * ref_to_ptr(T &);
100template<typename T> T const * ref_to_ptr(T const &);
101template<typename T> T volatile * ref_to_ptr(T volatile &);
102template<typename T> T const volatile * ref_to_ptr(T const volatile &);
103
104template<typename T> T * ref_to_ptr(T * const volatile &);
105
106template<typename T>
107struct cv_code
108{
109 static T _t;
110 BOOST_STATIC_CONSTANT(std::size_t, value =
111 sizeof(::ndnboost::function_types::detail::switch_cv(
112 ::ndnboost::function_types::detail::ref_to_ptr(_t) ) ));
113};
114
115template<typename T> struct cv_traits
116{
117 typedef typename ndnboost::function_types::detail::cv_tag_impl<
118 ::ndnboost::function_types::detail::cv_code<T>::value >::type
119 tag;
120
121 // may require Boost.TypeTraits broken compiler specializations
122 // to work
123 typedef typename ndnboost::remove_cv<
124 typename ndnboost::remove_pointer<
125 typename ndnboost::remove_reference<T>::type
126 >::type
127 >::type type;
128};
129#endif
130
131} } } // namespace ndnboost::function_types::detail
132
133#endif
134