Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * include/stxxl/bits/common/tmeta.h 00003 * 00004 * Template Metaprogramming Tools 00005 * (from the Generative Programming book Krysztof Czarnecki, Ulrich Eisenecker) 00006 * 00007 * Part of the STXXL. See http://stxxl.sourceforge.net 00008 * 00009 * Copyright (C) 2003 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00010 * Copyright (C) 2008 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00011 * 00012 * Distributed under the Boost Software License, Version 1.0. 00013 * (See accompanying file LICENSE_1_0.txt or copy at 00014 * http://www.boost.org/LICENSE_1_0.txt) 00015 **************************************************************************/ 00016 00017 #ifndef STXXL_META_TEMPLATE_PROGRAMMING 00018 #define STXXL_META_TEMPLATE_PROGRAMMING 00019 00020 #include <stxxl/bits/namespace.h> 00021 #include <stxxl/bits/common/types.h> 00022 00023 00024 __STXXL_BEGIN_NAMESPACE 00025 00026 //! \brief IF template metaprogramming statement 00027 00028 //! If \c Flag is \c true then \c IF<>::result is of type Type1 00029 //! otherwise of \c IF<>::result is of type Type2 00030 template <bool Flag, class Type1, class Type2> 00031 struct IF 00032 { 00033 typedef Type1 result; 00034 }; 00035 00036 template <class Type1, class Type2> 00037 struct IF<false, Type1, Type2> 00038 { 00039 typedef Type2 result; 00040 }; 00041 00042 00043 //! If \c Flag is \c true then \c IF<>::result is Num1 00044 //! otherwise of \c IF<>::result is Num2 00045 template <bool Flag, unsigned Num1, unsigned Num2> 00046 struct IF_N 00047 { 00048 enum 00049 { 00050 result = Num1 00051 }; 00052 }; 00053 00054 template <unsigned Num1, unsigned Num2> 00055 struct IF_N<false, Num1, Num2> 00056 { 00057 enum 00058 { 00059 result = Num2 00060 }; 00061 }; 00062 00063 const int DEFAULT = ~(~0u >> 1); // initialize with the smallest int 00064 00065 struct NilCase { }; 00066 00067 template <int tag_, class Type_, class Next_ = NilCase> 00068 struct CASE 00069 { 00070 enum { tag = tag_ }; 00071 typedef Type_ Type; 00072 typedef Next_ Next; 00073 }; 00074 00075 template <int tag, class Case> 00076 class SWITCH 00077 { 00078 typedef typename Case::Next NextCase; 00079 enum 00080 { 00081 caseTag = Case::tag, 00082 found = (caseTag == tag || caseTag == DEFAULT) 00083 }; 00084 00085 public: 00086 typedef typename IF<found, 00087 typename Case::Type, 00088 typename SWITCH<tag, NextCase>::result 00089 >::result result; 00090 }; 00091 00092 template <int tag> 00093 class SWITCH<tag, NilCase> 00094 { 00095 public: 00096 typedef NilCase result; 00097 }; 00098 00099 //! \internal, use LOG2 instead 00100 template <unsigned_type Input> 00101 class LOG2_floor 00102 { 00103 public: 00104 enum 00105 { 00106 value = LOG2_floor<Input / 2>::value + 1 00107 }; 00108 }; 00109 00110 template <> 00111 class LOG2_floor<1> 00112 { 00113 public: 00114 enum 00115 { 00116 value = 0 00117 }; 00118 }; 00119 00120 template <> 00121 class LOG2_floor<0> 00122 { 00123 public: 00124 enum 00125 { 00126 value = 0 00127 }; 00128 }; 00129 00130 template <unsigned_type Input> 00131 class LOG2 00132 { 00133 public: 00134 enum 00135 { 00136 floor = LOG2_floor<Input>::value, 00137 ceil = LOG2_floor<Input - 1>::value + 1 00138 }; 00139 }; 00140 00141 template <> 00142 class LOG2<1> 00143 { 00144 public: 00145 enum 00146 { 00147 floor = 0, 00148 ceil = 0 00149 }; 00150 }; 00151 00152 template <> 00153 class LOG2<0> 00154 { 00155 public: 00156 enum 00157 { 00158 floor = 0, 00159 ceil = 0 00160 }; 00161 }; 00162 00163 __STXXL_END_NAMESPACE 00164 00165 #endif // !STXXL_META_TEMPLATE_PROGRAMMING