00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef BOOST_ENUM_MACROS_HPP
00011 #define BOOST_ENUM_MACROS_HPP
00012
00013
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
00015 # pragma once
00016 #endif
00017
00018 #include <boost/preprocessor.hpp>
00019
00020 #define BOOST_ENUM_IS_COLUMN_2(i, k) \
00021 BOOST_PP_EQUAL(BOOST_PP_MOD(i, 2), k)
00022
00023 #define BOOST_ENUM_GET_COLUMN_2(r, data, i, elem) \
00024 BOOST_PP_IF(BOOST_ENUM_IS_COLUMN_2(i, data), (elem), BOOST_PP_EMPTY())
00025
00026 #define BOOST_ENUM_VISITOR1(_seq, _macro, _col) \
00027 BOOST_PP_SEQ_FOR_EACH(_macro, _, _seq)
00028
00029 #define BOOST_ENUM_VISITOR2(_seq, _macro, _col) \
00030 BOOST_PP_SEQ_FOR_EACH( \
00031 _macro, \
00032 _, \
00033 BOOST_PP_SEQ_FOR_EACH_I(BOOST_ENUM_GET_COLUMN_2, _col, _seq) \
00034 )
00035
00036 #define BOOST_ENUM_DOMAIN_ITEM(r, data, elem) \
00037 elem BOOST_PP_COMMA()
00038
00039 #define BOOST_ENUM_domain(_seq, _col, _colsize) \
00040 enum domain \
00041 { \
00042 BOOST_PP_CAT(BOOST_ENUM_VISITOR, _colsize) \
00043 (_seq, BOOST_ENUM_DOMAIN_ITEM, _col) \
00044 }; \
00045 BOOST_STATIC_CONSTANT(index_type, size = BOOST_ENUM_size(_seq, _colsize));
00046
00047 #define BOOST_ENUM_size(_seq, _colsize) \
00048 BOOST_PP_DIV(BOOST_PP_SEQ_SIZE(_seq), _colsize)
00049
00050 #define BOOST_ENUM_PARSE_ITEM(r, data, elem) \
00051 if(strcmp(str, BOOST_PP_STRINGIZE(elem)) == 0) return optional(elem);
00052
00053 #define BOOST_ENUM_get_by_name(_name, _seq, _col, _colsize) \
00054 static optional get_by_name(const char* str) \
00055 { \
00056 BOOST_PP_CAT(BOOST_ENUM_VISITOR, _colsize) \
00057 (_seq, BOOST_ENUM_PARSE_ITEM, _col) \
00058 return optional(); \
00059 }
00060
00061 #define BOOST_ENUM_CASE_STRING(r, data, elem) \
00062 case elem: return BOOST_PP_STRINGIZE(elem);
00063
00064 #define BOOST_ENUM_names(_seq, _col, _colsize) \
00065 static const char* names(domain index) \
00066 { \
00067 BOOST_ASSERT(static_cast<index_type>(index) < size); \
00068 switch(index) \
00069 { \
00070 BOOST_PP_CAT(BOOST_ENUM_VISITOR, _colsize) \
00071 (_seq, BOOST_ENUM_CASE_STRING, _col) \
00072 default: return NULL; \
00073 } \
00074 }
00075
00076 #define BOOST_ENUM_CASE_PART(elem) \
00077 case (elem):
00078
00079 #define BOOST_ENUM_VALUE_PART(elem) \
00080 return optional_value(elem);
00081
00082 #define BOOST_ENUM_VALUE_LINE(r, data, i, elem) \
00083 BOOST_PP_IF(BOOST_ENUM_IS_COLUMN_2(i, 0), \
00084 BOOST_ENUM_CASE_PART(elem), \
00085 BOOST_ENUM_VALUE_PART(elem) \
00086 )
00087
00088 #define BOOST_ENUM_values_identity() \
00089 typedef boost::optional<value_type> optional_value; \
00090 static optional_value values(domain index) \
00091 { \
00092 if(static_cast<index_type>(index) < size) return optional_value(index); \
00093 return optional_value(); \
00094 }
00095
00096 #define BOOST_ENUM_values(_seq, _name_col, _value_col, _colsize) \
00097 typedef boost::optional<value_type> optional_value; \
00098 static optional_value values(domain index) \
00099 { \
00100 switch(index) \
00101 { \
00102 BOOST_PP_SEQ_FOR_EACH_I(BOOST_ENUM_VALUE_LINE, _, _seq) \
00103 default: return optional_value(); \
00104 } \
00105 }
00106
00107 #define BOOST_BITFIELD_names(_seq, _col, _colsize) \
00108 static const char* names(domain index) \
00109 { \
00110 BOOST_ASSERT(static_cast<index_type>(index) < size); \
00111 switch(index) \
00112 { \
00113 case all_mask: return "all_mask"; \
00114 BOOST_PP_CAT(BOOST_ENUM_VISITOR, _colsize) \
00115 (_seq, BOOST_ENUM_CASE_STRING, _col) \
00116 default: return NULL; \
00117 } \
00118 }
00119
00120 #define BOOST_BITFIELD_OR_ITEM(r, data, elem) \
00121 | (elem)
00122
00123 #define BOOST_BITFIELD_domain(_seq, _col, _colsize) \
00124 enum domain \
00125 { \
00126 BOOST_PP_CAT(BOOST_ENUM_VISITOR, _colsize) \
00127 (_seq, BOOST_ENUM_DOMAIN_ITEM, _col) \
00128 all_mask, \
00129 not_mask \
00130 }; \
00131 BOOST_STATIC_CONSTANT(index_type, size = BOOST_ENUM_size(_seq, _colsize));
00132
00133 #define BOOST_BITFIELD_all_mask(_seq, _col, _colsize) \
00134 0 BOOST_PP_CAT(BOOST_ENUM_VISITOR, _colsize) \
00135 (_seq, BOOST_BITFIELD_OR_ITEM, _col)
00136
00137 #define BOOST_BITFIELD_get_by_name(_name, _seq, _col, _colsize) \
00138 static optional get_by_name(const char* str) \
00139 { \
00140 if(strcmp(str, "all_mask") == 0) return optional(all_mask); \
00141 if(strcmp(str, "not_mask") == 0) return optional(not_mask); \
00142 BOOST_PP_CAT(BOOST_ENUM_VISITOR, _colsize) \
00143 (_seq, BOOST_ENUM_PARSE_ITEM, _col) \
00144 return optional(); \
00145 }
00146
00147 #define BOOST_BITFIELD_values(_seq, _name_col, _value_col, _colsize) \
00148 typedef boost::optional<value_type> optional_value; \
00149 static optional_value values(domain index) \
00150 { \
00151 switch(index) \
00152 { \
00153 BOOST_PP_SEQ_FOR_EACH_I(BOOST_ENUM_VALUE_LINE, _, _seq) \
00154 case all_mask: return optional_value(BOOST_BITFIELD_all_mask(_seq, _value_col, _colsize)); \
00155 case not_mask: return optional_value(~(BOOST_BITFIELD_all_mask(_seq, _value_col, _colsize))); \
00156 default: return optional_value(); \
00157 } \
00158 }
00159
00160 #define BOOST_ENUM(_name, _seq) \
00161 class _name : public boost::detail::enum_base<_name> \
00162 { \
00163 public: \
00164 BOOST_ENUM_domain(_seq, 0, 1) \
00165 _name() {} \
00166 _name(domain index) : boost::detail::enum_base<_name>(index) {} \
00167 BOOST_ENUM_get_by_name(_name, _seq, 0, 1) \
00168 private: \
00169 friend class boost::detail::enum_base<_name>; \
00170 BOOST_ENUM_names(_seq, 0, 1) \
00171 BOOST_ENUM_values_identity() \
00172 };
00173
00174 #define BOOST_ENUM_VALUES(_name, _type, _seq) \
00175 class _name : public boost::detail::enum_base<_name, _type> \
00176 { \
00177 public: \
00178 BOOST_ENUM_domain(_seq, 0, 2) \
00179 _name() {} \
00180 _name(domain index) : boost::detail::enum_base<_name, _type>(index) {} \
00181 BOOST_ENUM_get_by_name(_name, _seq, 0, 2) \
00182 private: \
00183 friend class boost::detail::enum_base<_name, _type>; \
00184 BOOST_ENUM_names(_seq, 0, 2) \
00185 BOOST_ENUM_values(_seq, 0, 1, 2) \
00186 };
00187
00188 #define BOOST_BITFIELD(_name, _seq) \
00189 class _name : public boost::detail::bitfield_base<_name> \
00190 { \
00191 public: \
00192 BOOST_BITFIELD_domain(_seq, 0, 2) \
00193 _name() {} \
00194 _name(domain index) : boost::detail::bitfield_base<_name>(index) {} \
00195 BOOST_ENUM_get_by_name(_name, _seq, 0, 2) \
00196 private: \
00197 friend class boost::detail::bitfield_access; \
00198 _name(value_type raw, int) : boost::detail::bitfield_base<_name>(raw, 0) {} \
00199 BOOST_BITFIELD_names(_seq, 0, 2) \
00200 BOOST_BITFIELD_values(_seq, 0, 1, 2) \
00201 };
00202
00203 #endif