Stxxl
1.2.1
|
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 * 00011 * Distributed under the Boost Software License, Version 1.0. 00012 * (See accompanying file LICENSE_1_0.txt or copy at 00013 * http://www.boost.org/LICENSE_1_0.txt) 00014 **************************************************************************/ 00015 00016 #ifndef STXXL_META_TEMPLATE_PROGRAMMING 00017 #define STXXL_META_TEMPLATE_PROGRAMMING 00018 00019 #include <stxxl/bits/namespace.h> 00020 #include <stxxl/bits/common/types.h> 00021 00022 00023 __STXXL_BEGIN_NAMESPACE 00024 00026 00029 template <bool Flag, class Type1, class Type2> 00030 struct IF 00031 { 00032 typedef Type1 result; 00033 }; 00034 00035 template <class Type1, class Type2> 00036 struct IF<false, Type1, Type2> 00037 { 00038 typedef Type2 result; 00039 }; 00040 00041 00044 template <bool Flag, unsigned Num1, unsigned Num2> 00045 struct IF_N 00046 { 00047 enum 00048 { 00049 result = Num1 00050 }; 00051 }; 00052 00053 template <unsigned Num1, unsigned Num2> 00054 struct IF_N<false, Num1, Num2> 00055 { 00056 enum 00057 { 00058 result = Num2 00059 }; 00060 }; 00061 00062 const int DEFAULT = ~(~0u >> 1); // initialize with the smallest int 00063 00064 struct NilCase { }; 00065 00066 template <int tag_, class Type_, class Next_ = NilCase> 00067 struct CASE 00068 { 00069 enum { tag = tag_ }; 00070 typedef Type_ Type; 00071 typedef Next_ Next; 00072 }; 00073 00074 template <int tag, class Case> 00075 class SWITCH 00076 { 00077 typedef typename Case::Next NextCase; 00078 enum 00079 { 00080 caseTag = Case::tag, 00081 found = (caseTag == tag || caseTag == DEFAULT) 00082 }; 00083 00084 public: 00085 typedef typename IF<found, 00086 typename Case::Type, 00087 typename SWITCH<tag, NextCase>::result 00088 >::result result; 00089 }; 00090 00091 template <int tag> 00092 class SWITCH<tag, NilCase> 00093 { 00094 public: 00095 typedef NilCase result; 00096 }; 00097 00099 template <unsigned_type Input> 00100 class LOG2_floor 00101 { 00102 public: 00103 enum 00104 { 00105 value = LOG2_floor<Input / 2>::value + 1 00106 }; 00107 }; 00108 00109 template <> 00110 class LOG2_floor<1> 00111 { 00112 public: 00113 enum 00114 { 00115 value = 0 00116 }; 00117 }; 00118 00119 template <> 00120 class LOG2_floor<0> 00121 { 00122 public: 00123 enum 00124 { 00125 value = 0 00126 }; 00127 }; 00128 00129 template <unsigned_type Input> 00130 class LOG2 00131 { 00132 public: 00133 enum 00134 { 00135 floor = LOG2_floor<Input>::value, 00136 ceil = LOG2_floor<Input - 1>::value + 1 00137 }; 00138 }; 00139 00140 template <> 00141 class LOG2<1> 00142 { 00143 public: 00144 enum 00145 { 00146 floor = 0, 00147 ceil = 0 00148 }; 00149 }; 00150 00151 template <> 00152 class LOG2<0> 00153 { 00154 public: 00155 enum 00156 { 00157 floor = 0, 00158 ceil = 0 00159 }; 00160 }; 00161 00162 __STXXL_END_NAMESPACE 00163 00164 #endif // !STXXL_META_TEMPLATE_PROGRAMMING