Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:50

0001 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
0002 // (C) Copyright 2004-2007 Jonathan Turkanis
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
0005 
0006 // See http://www.boost.org/libs/iostreams for documentation.
0007 
0008 //
0009 // Intended as an alternative to type_traits::yes_type and type_traits::no_type.
0010 // Provides an arbitrary number of types (case_<0>, case_<1>, ...) for
0011 // determining the results of overload resultion using 'sizeof', plus a uniform
0012 // means of using the result. yes_type and no_type are typedefs for case_<1>
0013 // and case_<0>. A single case with negative argument, case_<-1>, is also 
0014 // provided, for convenience.
0015 //
0016 // This header may be included any number of times, with
0017 // BOOST_SELECT_BY_SIZE_MAX_CASE defined to be the largest N such that case_<N>
0018 // is needed for a particular application. It defaults to 20.
0019 //
0020 // This header depends only on Boost.Config and Boost.Preprocessor. Dependence
0021 // on Type Traits or MPL was intentionally avoided, to leave open the 
0022 // possibility that select_by_size could be used by these libraries.
0023 //
0024 // Example usage:
0025 //
0026 //    #define BOOST_SELECT_BY_SIZE_MAX_CASE 7   // (Needed when default was 2)
0027 //    #include <boost/utility/select_by_size.hpp>
0028 //
0029 //    using namespace boost::utility;
0030 //
0031 //    case_<0> helper(bool);
0032 //    case_<1> helper(int);
0033 //    case_<2> helper(unsigned);
0034 //    case_<3> helper(long);
0035 //    case_<4> helper(unsigned long);
0036 //    case_<5> helper(float);
0037 //    case_<6> helper(double);
0038 //    case_<7> helper(const char*);
0039 //
0040 //    struct test {
0041 //        static const int value =
0042 //            select_by_size< sizeof(helper(9876UL)) >::value;
0043 //        BOOST_STATIC_ASSERT(value == 4);
0044 //    };
0045 //
0046 // For compilers with integral constant expression problems, e.g. Borland 5.x,
0047 // one can also write
0048 //
0049 //    struct test {
0050 //        BOOST_SELECT_BY_SIZE(int, value, helper(9876UL));
0051 //    };
0052 //
0053 // to define a static integral constant 'value' equal to
0054 //
0055 //    select_by_size< sizeof(helper(9876UL)) >::value.
0056 //
0057 
0058 // Include guards surround all contents of this header except for explicit
0059 // specializations of select_by_size for case_<N> with N > 2.
0060 
0061 #ifndef BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED
0062 #define BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED
0063 
0064 // The lowest N for which select_by_size< sizeof(case_<N>) > has not been
0065 // specialized.
0066 #define SELECT_BY_SIZE_MAX_SPECIALIZED 20
0067 
0068 #include <boost/config.hpp>    // BOOST_STATIC_CONSTANT.
0069 #include <boost/preprocessor/cat.hpp>
0070 #include <boost/preprocessor/iteration/local.hpp>
0071 
0072 /* Alternative implementation using max_align. 
0073 
0074 #include <boost/type_traits/alignment_of.hpp>
0075 #include <boost/type_traits/type_with_alignment.hpp>
0076 
0077 namespace boost { namespace utility {
0078 
0079 template<int N>
0080 struct case_ { char c[(N + 1) * alignment_of<detail::max_align>::value]; };
0081 
0082 template<unsigned Size>
0083 struct select_by_size {
0084     BOOST_STATIC_CONSTANT(int, value = 
0085         (Size / alignment_of<detail::max_align>::value - 1));
0086 };
0087 
0088 } } // End namespaces utility, boost.
0089 
0090 */              // End alternate implementation.
0091 
0092 namespace boost { namespace iostreams { namespace detail {
0093 
0094 //--------------Definition of case_-------------------------------------------//
0095 
0096 template<int N> struct case_ { char c1; case_<N - 1> c2; };
0097 template<> struct case_<-1> { char c; };
0098 typedef case_<true> yes_type;
0099 typedef case_<false> no_type;
0100 
0101 //--------------Declaration of select_by_size---------------------------------//
0102 
0103 template<unsigned Size> struct select_by_size;
0104 
0105 } } } // End namespaces detail, iostreams, boost.
0106 
0107 //--------------Definition of SELECT_BY_SIZE_SPEC-----------------------------//
0108 
0109 // Sepecializes select_by_size for sizeof(case<n-1>). The decrement is used
0110 // here because the preprocessor library doesn't handle negative integers.
0111 #define SELECT_BY_SIZE_SPEC(n) \
0112     namespace boost { namespace iostreams { namespace detail { \
0113       static const int BOOST_PP_CAT(sizeof_case_, n) = sizeof(case_<n - 1>); \
0114       template<> \
0115       struct select_by_size< BOOST_PP_CAT(sizeof_case_, n) > { \
0116           struct type { BOOST_STATIC_CONSTANT(int, value = n - 1); }; \
0117           BOOST_STATIC_CONSTANT(int, value = type::value); \
0118       }; \
0119     } } } \
0120     /**/
0121 
0122 //--------------Default specializations of select_by_size---------------------//
0123 
0124 #define BOOST_PP_LOCAL_MACRO(n) SELECT_BY_SIZE_SPEC(n)
0125 #define BOOST_PP_LOCAL_LIMITS (0, 20)
0126 #include BOOST_PP_LOCAL_ITERATE()
0127 #undef BOOST_PP_LOCAL_MACRO
0128 
0129 //--------------Definition of SELECT_BY_SIZE----------------------------------//
0130 
0131 #define BOOST_SELECT_BY_SIZE(type_, name, expr) \
0132     BOOST_STATIC_CONSTANT( \
0133         unsigned, \
0134         BOOST_PP_CAT(boost_select_by_size_temp_, name) = sizeof(expr) \
0135     ); \
0136     BOOST_STATIC_CONSTANT( \
0137         type_, \
0138         name = \
0139             ( ::boost::iostreams::detail::select_by_size< \
0140                 BOOST_PP_CAT(boost_select_by_size_temp_, name) \
0141               >::value ) \
0142     ) \
0143     /**/
0144 
0145 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED
0146 
0147 //----------Specializations of SELECT_BY_SIZE (outside main inclued guards)---//
0148 
0149 #if defined(BOOST_SELECT_BY_SIZE_MAX_CASE) && \
0150     BOOST_SELECT_BY_SIZE_MAX_CASE > SELECT_BY_SIZE_MAX_SPECIALIZED
0151 
0152 #define BOOST_PP_LOCAL_MACRO(n) SELECT_BY_SIZE_SPEC(n)
0153 #define BOOST_PP_LOCAL_LIMITS \
0154     (SELECT_BY_SIZE_MAX_SPECIALIZED, BOOST_SELECT_BY_SIZE_MAX_CASE) \
0155     /**/
0156 #include BOOST_PP_LOCAL_ITERATE()
0157 #undef BOOST_PP_LOCAL_MACRO
0158 #undef SELECT_BY_SIZE_MAX_SPECIALIZED
0159 #define SELECT_BY_SIZE_MAX_SPECIALIZED BOOST_SELECT_BY_SIZE_MAX_CASE
0160 
0161 #endif