Alchemy
1.0
A framework to robustly process network messages and structured data
Main Page
Related Pages
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Pages
Pb
auto_index.h
1
/// @file meta/auto_index_MACROS.h
2
///
3
/// Provides a construct to auto-increment an index at compile-time.
4
///
5
/// The MIT License(MIT)
6
/// @copyright 2014 Paul M Watt
7
// ****************************************************************************
8
#ifndef AUTO_INDEX_H_INCLUDED
9
#define AUTO_INDEX_H_INCLUDED
10
// Includes *******************************************************************
11
#include <Pb/meta_util.h>
12
13
namespace
Hg
14
{
15
16
#define HAS_COUNTER
17
#if defined(HAS_COUNTER)
18
19
// ****************************************************************************
20
// This version is not portable because it depends upon the __COUNTER__ macro.
21
// However, until a more portable implementation for the version above can
22
// be implemented, this version is simple, and works for many compilers.
23
//
24
25
// ****************************************************************************
26
#define BEGIN_COUNTER static const size_t k_enum_base = __COUNTER__ + 1;
27
28
// ****************************************************************************
29
#define INC_COUNTER
30
31
// ****************************************************************************
32
#define COUNTER_VALUE (__COUNTER__ - k_enum_base)
33
34
// ****************************************************************************
35
#define END_ENUM
36
37
#elif defined(_WIN32)
38
39
// **************************************************************************
40
// It turns out that the way this implementation is integrated with the
41
// Hg objects is not portable because the standard does not allow template
42
// specialization to occur within a class scope.
43
//
44
// This version will still be used for WIN32 builds.
45
// The __COUNTER__ MACRO will be used for other compilers that support it.
46
// When a compiler is encountered that does not support either possibility,
47
// this issue will be revisited.
48
//
49
50
// Forward Declarations *****************************************************
51
#define FORWARD_DECLARE_AUTO_INDEX \
52
template <int L> \
53
struct decrement_until_match;
54
55
// **************************************************************************
56
#define ENUM_BEGIN \
57
template<int N> \
58
struct enum_begin \
59
: std::integral_constant<int, N> \
60
{ };
61
62
// **************************************************************************
63
#define ENUM_ENTRY_INVALID \
64
template<int N, bool IsValidT = false> \
65
struct enum_entry \
66
: std::integral_constant<bool, IsValidT> \
67
{ };
68
69
// **************************************************************************
70
#define ENUM_ENTRY_VALID \
71
template<int N> \
72
struct enum_entry<N, true> \
73
: std::true_type \
74
{};
75
76
// **************************************************************************
77
#define ENUM_ENTRY_ZERO \
78
template<> \
79
struct enum_entry<0, true> \
80
: std::true_type \
81
{};
82
83
// **************************************************************************
84
#define AUTO_INDEX_BEFORE \
85
template <int L> \
86
struct index_before \
87
: std::integral_constant< int, \
88
decrement_until_match<L - 1>::value \
89
> \
90
{ };
91
92
// **************************************************************************
93
#define AUTO_INDEX_NEXT \
94
template <int L> \
95
struct auto_index \
96
: std::integral_constant< int, index_before<L>::value + 1 > \
97
{ };
98
99
// **************************************************************************
100
#define AUTO_INDEX_ZERO \
101
template <> \
102
struct auto_index<0> \
103
: std::integral_constant< int, -1> \
104
{ };
105
106
// **************************************************************************
107
#define DECREMENT_UNTIL_MATCH \
108
template <int L> \
109
struct decrement_until_match \
110
: std::integral_constant< int, \
111
value_if< enum_entry<L>::value, \
112
int, \
113
auto_index<L>::value, \
114
decrement_until_match<L - 1>::value \
115
>::value \
116
> \
117
{ };
118
119
// **************************************************************************
120
#define DECREMENT_UNTIL_ZERO \
121
template <> \
122
struct decrement_until_match<0> \
123
: std::integral_constant <int, -1> \
124
{ };
125
126
// **************************************************************************
127
#define ADD_ENUM_H(ID) \
128
template<> \
129
struct enum_entry<(ID)> \
130
: std::true_type \
131
{ };
132
133
134
// **************************************************************************
135
#define BEGIN_COUNTER \
136
FORWARD_DECLARE_AUTO_INDEX \
137
ENUM_BEGIN \
138
ENUM_ENTRY_INVALID \
139
ENUM_ENTRY_VALID \
140
ENUM_ENTRY_ZERO \
141
AUTO_INDEX_BEFORE \
142
AUTO_INDEX_NEXT \
143
AUTO_INDEX_ZERO \
144
DECREMENT_UNTIL_MATCH \
145
DECREMENT_UNTIL_ZERO \
146
typedef std::integral_constant<int, __LINE__> enum_base;
147
148
// ****************************************************************************
149
#define INC_COUNTER ADD_ENUM_H(__LINE__ - enum_base::value)
150
151
// ****************************************************************************
152
#define COUNTER_VALUE (auto_index<__LINE__- enum_base::value>::value)
153
154
// ****************************************************************************
155
#define END_ENUM
156
157
#else
158
159
#error "An auto-incrementing index is not available for this compiler. Manual index items will be required."
160
161
#endif
162
163
164
}
// namespace Hg
165
166
#endif
167
Generated on Sat May 9 2015 21:25:05 for Alchemy by
1.8.3.1