From 464fef1efae6f60d7fe197f923c616af007e4722 Mon Sep 17 00:00:00 2001 From: Jonathan Turkanis Date: Wed, 11 Feb 2004 20:16:05 +0000 Subject: [PATCH] initial commitment [SVN r1963] --- select_by_size.html | 186 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 select_by_size.html diff --git a/select_by_size.html b/select_by_size.html new file mode 100644 index 0000000..247400e --- /dev/null +++ b/select_by_size.html @@ -0,0 +1,186 @@ + + + + + + + + +

Select By Size

+ +

+ + + + + + +
Author:Jonathan Turkanis
Contact:turkanis@kangaroologic.com
Date:2004-02-11
Copyright:Copyright Jonathan Turkanis 2004. All rights reserved
+

+ +

Contents

+ +
+
1. Overview +
2. Usage +
3. Rationale +
4. Synopsis +
5. Dependencies +
6. Portability +
+ + +

Overview

+ +

+ 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 template case_

+ +

+ 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 template select_by_size

+ +

+ 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
+

+ +

The macro BOOST_SELECT_BY_SIZE_MAX_CASE

+ +

+ 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

+ +

+ 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. +

+ + +

Usage

+ +
    #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);
+    };
+ + +

Rationale

+ +The utility of type_traits::yes_type and type_traits::no_type is well-known. The advantages of using select_by_size are: + + + +

+ 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>. +

+ +

+

+ + +

Synopsis

+ +
    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]
+      } 
+    }
+ + +

Dependencies

+ +The header <boost/utility/select_by_size.hpp> depends on Boost.Config and Boost.Preprocessor. + + +

Portability

+ +

+ 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