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