Stxxl  1.2.1
tmeta.h
1 /***************************************************************************
2  * include/stxxl/bits/common/tmeta.h
3  *
4  * Template Metaprogramming Tools
5  * (from the Generative Programming book Krysztof Czarnecki, Ulrich Eisenecker)
6  *
7  * Part of the STXXL. See http://stxxl.sourceforge.net
8  *
9  * Copyright (C) 2003 Roman Dementiev <dementiev@mpi-sb.mpg.de>
10  *
11  * Distributed under the Boost Software License, Version 1.0.
12  * (See accompanying file LICENSE_1_0.txt or copy at
13  * http://www.boost.org/LICENSE_1_0.txt)
14  **************************************************************************/
15 
16 #ifndef STXXL_META_TEMPLATE_PROGRAMMING
17 #define STXXL_META_TEMPLATE_PROGRAMMING
18 
19 #include <stxxl/bits/namespace.h>
20 #include <stxxl/bits/common/types.h>
21 
22 
23 __STXXL_BEGIN_NAMESPACE
24 
26 
29 template <bool Flag, class Type1, class Type2>
30 struct IF
31 {
32  typedef Type1 result;
33 };
34 
35 template <class Type1, class Type2>
36 struct IF<false, Type1, Type2>
37 {
38  typedef Type2 result;
39 };
40 
41 
44 template <bool Flag, unsigned Num1, unsigned Num2>
45 struct IF_N
46 {
47  enum
48  {
49  result = Num1
50  };
51 };
52 
53 template <unsigned Num1, unsigned Num2>
54 struct IF_N<false, Num1, Num2>
55 {
56  enum
57  {
58  result = Num2
59  };
60 };
61 
62 const int DEFAULT = ~(~0u >> 1); // initialize with the smallest int
63 
64 struct NilCase { };
65 
66 template <int tag_, class Type_, class Next_ = NilCase>
67 struct CASE
68 {
69  enum { tag = tag_ };
70  typedef Type_ Type;
71  typedef Next_ Next;
72 };
73 
74 template <int tag, class Case>
75 class SWITCH
76 {
77  typedef typename Case::Next NextCase;
78  enum
79  {
80  caseTag = Case::tag,
81  found = (caseTag == tag || caseTag == DEFAULT)
82  };
83 
84 public:
85  typedef typename IF<found,
86  typename Case::Type,
87  typename SWITCH<tag, NextCase>::result
88  >::result result;
89 };
90 
91 template <int tag>
92 class SWITCH<tag, NilCase>
93 {
94 public:
95  typedef NilCase result;
96 };
97 
99 template <unsigned_type Input>
101 {
102 public:
103  enum
104  {
105  value = LOG2_floor<Input / 2>::value + 1
106  };
107 };
108 
109 template <>
110 class LOG2_floor<1>
111 {
112 public:
113  enum
114  {
115  value = 0
116  };
117 };
118 
119 template <>
120 class LOG2_floor<0>
121 {
122 public:
123  enum
124  {
125  value = 0
126  };
127 };
128 
129 template <unsigned_type Input>
130 class LOG2
131 {
132 public:
133  enum
134  {
135  floor = LOG2_floor<Input>::value,
136  ceil = LOG2_floor<Input - 1>::value + 1
137  };
138 };
139 
140 template <>
141 class LOG2<1>
142 {
143 public:
144  enum
145  {
146  floor = 0,
147  ceil = 0
148  };
149 };
150 
151 template <>
152 class LOG2<0>
153 {
154 public:
155  enum
156  {
157  floor = 0,
158  ceil = 0
159  };
160 };
161 
162 __STXXL_END_NAMESPACE
163 
164 #endif // !STXXL_META_TEMPLATE_PROGRAMMING