From 464fef1efae6f60d7fe197f923c616af007e4722 Mon Sep 17 00:00:00 2001
From: Jonathan Turkanis
+Select By Size
+
+
+
+
+ Author: Jonathan Turkanis
+ Contact: turkanis@kangaroologic.com
+ Date: 2004-02-11
+Copyright: Copyright Jonathan Turkanis 2004. All rights reserved
+ The header <boost/utility/select_by_size.hpp> provides template classes and macros for determining the results of overload resolution at compile time using sizeof. It is intended as an alternative to type_traits::yes_type and type_traits::no_type from the Type Traits library. It provides an arbitrary number of types, case_<0>, case_<1>, case_<2>, ... , for use as the return types of helper functions, plus a template select_by_size which provides access to the result of the overload resolution. There is also a macro BOOST_SELECT_BY_SIZE, similar to BOOST_STATIC_CONSTANT, for use with compilers which have trouble with integral constant expressions. (See Coding Guidelines for Integral Constant Expressions.) For convenience, a single return type representing a negative value is also provided: case_<-1>. +
+ +All types decribes in this document reside in the namespace boost::utility. + +
+ The defining property of the class template case_ is that the sizes of the types +
case_<-1>, case_<0>, case_<1>, case_<2>, case_<3>, ...+form a strictly increasing sequence. With well-behaved implementations, sizeof(case_<-1>) will be small, as will be the difference in size between adjacent types in the sequence. + + +
+ The typedefs yes_type and no_type are provided as shorthands for case_<1> and case_<0>. Naturally, case_<true> and case_<false> may also be used. +
+ ++ The defining property of the class template select_by_size is that for each integer N in the range select_by_size through BOOST_SELECT_BY_SIZE_MAX_CASE, we have the equality +
select_by_size< sizeof(case_<N>) >::value == N+ + +
+ In order to make use of select_by_size with specializations case_<N> for N other than -1, 0 and 1, + the symbol BOOST_SELECT_BY_SIZE_MAX_CASE must be defined as an intergral value greater than or equal to N before including the header <boost/utility/select_by_size.hpp>. The header may be included multiple times with different values of BOOST_SELECT_BY_SIZE_MAX_CASE. +
+ ++ The macro BOOST_SELECT_BY_SIZE(type, name, expr) can be used similarly to BOOST_STATIC_CONSTANT to define a static const intergral class member name of type type with value equal to select_by_size< sizeof(expr) >::value. +
+ + +#include <boost/static_assert.hpp> + #define BOOST_SELECT_BY_SIZE_MAX_CASE 7 + #include <boost/utility/select_by_size.hpp> + + using namespace boost::utility; + + case_<0> helper(bool); + case_<1> helper(int); + case_<2> helper(unsigned); + case_<3> helper(long); + case_<4> helper(unsigned long); + case_<5> helper(float); + case_<6> helper(double); + case_<7> helper(const char*); + + struct test { + static const int value = + select_by_size< sizeof(helper("hello")) >::value; + BOOST_STATIC_ASSERT(value == 7); + }; + + struct test2 { + BOOST_SELECT_BY_SIZE(int, value, helper("hello")); + BOOST_STATIC_ASSERT(value == 7); + };+ + +
+ Until recently the author was aware of only one use for item (3). Thus he regarded the use of select_by_size with more than two cases as a trick. He then discovered a second use, elevating it to a method. With the discovery of a third use, it is now a programming paradigm. The three known uses are determing template arity, as in <boost/mpl/aux_/template_arity.hpp>, Joel de Guzman's type deduction system in the Boost Sandbox at <boost/utility/type_deduction.hpp>, and Reece Dunn's type deduction system for his Output Formatters library, also in the Boost Sandbox, at <boost/outfmt/detail/type_traits.hpp>. +
+ ++
+ + +namespace boost { + namespace utility { + + template<int N> struct case_; + + template<unsigned N> + struct select_by_size { + struct type { + static const unsigned value = + [M such that sizeof(case_<M>) == N]; + }; + static const unsigned value = type::value; + }; + + #define BOOST_SELECT_BY_SIZE(type, name, expr) [implementation-defined] + } + }+ + +
+ The program <libs/utility/select_by_size_test.cpp> has been tested successfully with the following compilers: +
+ © Copyright Jonathan Turkanis 2004. + Permission to copy, use, modify, sell and distribute this document + is granted provided this copyright notice appears in all copies. This + document is provided "as is" without express or implied warranty, and + with no claim as to its suitability for any purpose. +
+ + \ No newline at end of file