]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/iostreams/include/boost/iostreams/detail/select_by_size.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / iostreams / include / boost / iostreams / detail / select_by_size.hpp
1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2 // (C) Copyright 2004-2007 Jonathan Turkanis
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
5
6 // See http://www.boost.org/libs/iostreams for documentation.
7
8 //
9 // Intended as an alternative to type_traits::yes_type and type_traits::no_type.
10 // Provides an arbitrary number of types (case_<0>, case_<1>, ...) for
11 // determining the results of overload resultion using 'sizeof', plus a uniform
12 // means of using the result. yes_type and no_type are typedefs for case_<1>
13 // and case_<0>. A single case with negative argument, case_<-1>, is also
14 // provided, for convenience.
15 //
16 // This header may be included any number of times, with
17 // BOOST_SELECT_BY_SIZE_MAX_CASE defined to be the largest N such that case_<N>
18 // is needed for a particular application. It defaults to 20.
19 //
20 // This header depends only on Boost.Config and Boost.Preprocessor. Dependence
21 // on Type Traits or MPL was intentionally avoided, to leave open the
22 // possibility that select_by_size could be used by these libraries.
23 //
24 // Example usage:
25 //
26 // #define BOOST_SELECT_BY_SIZE_MAX_CASE 7 // (Needed when default was 2)
27 // #include <boost/utility/select_by_size.hpp>
28 //
29 // using namespace boost::utility;
30 //
31 // case_<0> helper(bool);
32 // case_<1> helper(int);
33 // case_<2> helper(unsigned);
34 // case_<3> helper(long);
35 // case_<4> helper(unsigned long);
36 // case_<5> helper(float);
37 // case_<6> helper(double);
38 // case_<7> helper(const char*);
39 //
40 // struct test {
41 // static const int value =
42 // select_by_size< sizeof(helper(9876UL)) >::value;
43 // BOOST_STATIC_ASSERT(value == 4);
44 // };
45 //
46 // For compilers with integral constant expression problems, e.g. Borland 5.x,
47 // one can also write
48 //
49 // struct test {
50 // BOOST_SELECT_BY_SIZE(int, value, helper(9876UL));
51 // };
52 //
53 // to define a static integral constant 'value' equal to
54 //
55 // select_by_size< sizeof(helper(9876UL)) >::value.
56 //
57
58 // Include guards surround all contents of this header except for explicit
59 // specializations of select_by_size for case_<N> with N > 2.
60
61 #ifndef BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED
62 #define BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED
63
64 // The lowest N for which select_by_size< sizeof(case_<N>) > has not been
65 // specialized.
66 #define SELECT_BY_SIZE_MAX_SPECIALIZED 20
67
68 #include <boost/config.hpp> // BOOST_STATIC_CONSTANT.
69 #include <boost/preprocessor/cat.hpp>
70 #include <boost/preprocessor/iteration/local.hpp>
71
72 /* Alternative implementation using max_align.
73
74 #include <boost/type_traits/alignment_of.hpp>
75 #include <boost/type_traits/type_with_alignment.hpp>
76
77 namespace boost { namespace utility {
78
79 template<int N>
80 struct case_ { char c[(N + 1) * alignment_of<detail::max_align>::value]; };
81
82 template<unsigned Size>
83 struct select_by_size {
84 BOOST_STATIC_CONSTANT(int, value =
85 (Size / alignment_of<detail::max_align>::value - 1));
86 };
87
88 } } // End namespaces utility, boost.
89
90 */ // End alternate implementation.
91
92 namespace boost { namespace iostreams { namespace detail {
93
94 //--------------Definition of case_-------------------------------------------//
95
96 template<int N> struct case_ { char c1; case_<N - 1> c2; };
97 template<> struct case_<-1> { char c; };
98 typedef case_<true> yes_type;
99 typedef case_<false> no_type;
100
101 //--------------Declaration of select_by_size---------------------------------//
102
103 template<unsigned Size> struct select_by_size;
104
105 } } } // End namespaces detail, iostreams, boost.
106
107 //--------------Definition of SELECT_BY_SIZE_SPEC-----------------------------//
108
109 // Sepecializes select_by_size for sizeof(case<n-1>). The decrement is used
110 // here because the preprocessor library doesn't handle negative integers.
111 #define SELECT_BY_SIZE_SPEC(n) \
112 namespace boost { namespace iostreams { namespace detail { \
113 static const int BOOST_PP_CAT(sizeof_case_, n) = sizeof(case_<n - 1>); \
114 template<> \
115 struct select_by_size< BOOST_PP_CAT(sizeof_case_, n) > { \
116 struct type { BOOST_STATIC_CONSTANT(int, value = n - 1); }; \
117 BOOST_STATIC_CONSTANT(int, value = type::value); \
118 }; \
119 } } } \
120 /**/
121
122 //--------------Default specializations of select_by_size---------------------//
123
124 #define BOOST_PP_LOCAL_MACRO(n) SELECT_BY_SIZE_SPEC(n)
125 #define BOOST_PP_LOCAL_LIMITS (0, 20)
126 #include BOOST_PP_LOCAL_ITERATE()
127 #undef BOOST_PP_LOCAL_MACRO
128
129 //--------------Definition of SELECT_BY_SIZE----------------------------------//
130
131 #define BOOST_SELECT_BY_SIZE(type_, name, expr) \
132 BOOST_STATIC_CONSTANT( \
133 unsigned, \
134 BOOST_PP_CAT(boost_select_by_size_temp_, name) = sizeof(expr) \
135 ); \
136 BOOST_STATIC_CONSTANT( \
137 type_, \
138 name = \
139 ( ::boost::iostreams::detail::select_by_size< \
140 BOOST_PP_CAT(boost_select_by_size_temp_, name) \
141 >::value ) \
142 ) \
143 /**/
144
145 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED
146
147 //----------Specializations of SELECT_BY_SIZE (outside main inclued guards)---//
148
149 #if defined(BOOST_SELECT_BY_SIZE_MAX_CASE) && \
150 BOOST_SELECT_BY_SIZE_MAX_CASE > SELECT_BY_SIZE_MAX_SPECIALIZED
151
152 #define BOOST_PP_LOCAL_MACRO(n) SELECT_BY_SIZE_SPEC(n)
153 #define BOOST_PP_LOCAL_LIMITS \
154 (SELECT_BY_SIZE_MAX_SPECIALIZED, BOOST_SELECT_BY_SIZE_MAX_CASE) \
155 /**/
156 #include BOOST_PP_LOCAL_ITERATE()
157 #undef BOOST_PP_LOCAL_MACRO
158 #undef SELECT_BY_SIZE_MAX_SPECIALIZED
159 #define SELECT_BY_SIZE_MAX_SPECIALIZED BOOST_SELECT_BY_SIZE_MAX_CASE
160
161 #endif