1 // Copyright (c) 2001-2011 Hartmut Kaiser 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #if !defined(BOOST_SPIRIT_ADAPT_ADT_ATTRIBUTES_SEP_15_2010_1219PM) 7 #define BOOST_SPIRIT_ADAPT_ADT_ATTRIBUTES_SEP_15_2010_1219PM 8 9 #if defined(_MSC_VER) 10 #pragma once 11 #endif 12 13 #include <boost/spirit/home/support/attributes.hpp> 14 #include <boost/spirit/home/support/container.hpp> 15 #include <boost/spirit/home/support/numeric_traits.hpp> 16 #include <boost/fusion/include/adapt_adt.hpp> 17 #include <boost/utility/enable_if.hpp> 18 19 /////////////////////////////////////////////////////////////////////////////// 20 // customization points allowing to use adapted classes with spirit 21 namespace boost { namespace spirit { namespace traits 22 { 23 /////////////////////////////////////////////////////////////////////////// 24 template <typename T, int N, bool Const, typename Domain> 25 struct not_is_variant< 26 fusion::extension::adt_attribute_proxy<T, N, Const>, Domain> 27 : not_is_variant< 28 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 29 , Domain> 30 {}; 31 32 template <typename T, int N, bool Const, typename Domain> 33 struct not_is_optional< 34 fusion::extension::adt_attribute_proxy<T, N, Const>, Domain> 35 : not_is_optional< 36 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 37 , Domain> 38 {}; 39 40 /////////////////////////////////////////////////////////////////////////// 41 template <typename T, int N, bool Const> 42 struct is_container<fusion::extension::adt_attribute_proxy<T, N, Const> > 43 : is_container< 44 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 45 > 46 {}; 47 48 template <typename T, int N, bool Const> 49 struct container_value<fusion::extension::adt_attribute_proxy<T, N, Const> > 50 : container_value< 51 typename remove_reference< 52 typename fusion::extension::adt_attribute_proxy< 53 T, N, Const 54 >::type 55 >::type 56 > 57 {}; 58 59 template <typename T, int N, bool Const> 60 struct container_value< 61 fusion::extension::adt_attribute_proxy<T, N, Const> const> 62 : container_value< 63 typename add_const< 64 typename remove_reference< 65 typename fusion::extension::adt_attribute_proxy< 66 T, N, Const 67 >::type 68 >::type 69 >::type 70 > 71 {}; 72 73 template <typename T, int N, typename Val> 74 struct push_back_container< 75 fusion::extension::adt_attribute_proxy<T, N, false> 76 , Val 77 , typename enable_if<is_reference< 78 typename fusion::extension::adt_attribute_proxy<T, N, false>::type 79 > >::type> 80 { callboost::spirit::traits::push_back_container81 static bool call( 82 fusion::extension::adt_attribute_proxy<T, N, false>& p 83 , Val const& val) 84 { 85 typedef typename 86 fusion::extension::adt_attribute_proxy<T, N, false>::type 87 type; 88 return push_back(type(p), val); 89 } 90 }; 91 92 template <typename T, int N, bool Const> 93 struct container_iterator< 94 fusion::extension::adt_attribute_proxy<T, N, Const> > 95 : container_iterator< 96 typename remove_reference< 97 typename fusion::extension::adt_attribute_proxy< 98 T, N, Const 99 >::type 100 >::type 101 > 102 {}; 103 104 template <typename T, int N, bool Const> 105 struct container_iterator< 106 fusion::extension::adt_attribute_proxy<T, N, Const> const> 107 : container_iterator< 108 typename add_const< 109 typename remove_reference< 110 typename fusion::extension::adt_attribute_proxy< 111 T, N, Const 112 >::type 113 >::type 114 >::type 115 > 116 {}; 117 118 template <typename T, int N, bool Const> 119 struct begin_container<fusion::extension::adt_attribute_proxy<T, N, Const> > 120 { 121 typedef typename remove_reference< 122 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 123 >::type container_type; 124 125 static typename container_iterator<container_type>::type callboost::spirit::traits::begin_container126 call(fusion::extension::adt_attribute_proxy<T, N, Const>& c) 127 { 128 return c.get().begin(); 129 } 130 }; 131 132 template <typename T, int N, bool Const> 133 struct begin_container<fusion::extension::adt_attribute_proxy<T, N, Const> const> 134 { 135 typedef typename add_const< 136 typename remove_reference< 137 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 138 >::type 139 >::type container_type; 140 141 static typename container_iterator<container_type>::type callboost::spirit::traits::begin_container142 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& c) 143 { 144 return c.get().begin(); 145 } 146 }; 147 148 template <typename T, int N, bool Const> 149 struct end_container<fusion::extension::adt_attribute_proxy<T, N, Const> > 150 { 151 typedef typename remove_reference< 152 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 153 >::type container_type; 154 155 static typename container_iterator<container_type>::type callboost::spirit::traits::end_container156 call(fusion::extension::adt_attribute_proxy<T, N, Const>& c) 157 { 158 return c.get().end(); 159 } 160 }; 161 162 template <typename T, int N, bool Const> 163 struct end_container<fusion::extension::adt_attribute_proxy<T, N, Const> const> 164 { 165 typedef typename add_const< 166 typename remove_reference< 167 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 168 >::type 169 >::type container_type; 170 171 static typename container_iterator<container_type>::type callboost::spirit::traits::end_container172 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& c) 173 { 174 return c.get().end(); 175 } 176 }; 177 178 /////////////////////////////////////////////////////////////////////////// 179 template <typename T, int N, typename Val> 180 struct assign_to_attribute_from_value< 181 fusion::extension::adt_attribute_proxy<T, N, false> 182 , Val> 183 { 184 static void callboost::spirit::traits::assign_to_attribute_from_value185 call(Val const& val 186 , fusion::extension::adt_attribute_proxy<T, N, false>& attr) 187 { 188 attr = val; 189 } 190 }; 191 192 template <typename T, int N, bool Const, typename Exposed> 193 struct extract_from_attribute< 194 fusion::extension::adt_attribute_proxy<T, N, Const>, Exposed> 195 { 196 typedef typename remove_const< 197 typename remove_reference< 198 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 199 >::type 200 >::type embedded_type; 201 typedef 202 typename spirit::result_of::extract_from<Exposed, embedded_type>::type 203 type; 204 205 template <typename Context> 206 static type callboost::spirit::traits::extract_from_attribute207 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val, Context& ctx) 208 { 209 return extract_from<Exposed>(val.get(), ctx); 210 } 211 }; 212 213 /////////////////////////////////////////////////////////////////////////// 214 template <typename T, int N, bool Const> 215 struct attribute_type<fusion::extension::adt_attribute_proxy<T, N, Const> > 216 : fusion::extension::adt_attribute_proxy<T, N, Const> 217 {}; 218 219 /////////////////////////////////////////////////////////////////////////// 220 template <typename T, int N, bool Const> 221 struct optional_attribute< 222 fusion::extension::adt_attribute_proxy<T, N, Const> > 223 { 224 typedef typename result_of::optional_value< 225 typename remove_reference< 226 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 227 >::type 228 >::type type; 229 230 static type callboost::spirit::traits::optional_attribute231 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 232 { 233 return optional_value(val.get()); 234 } 235 236 static bool is_validboost::spirit::traits::optional_attribute237 is_valid(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 238 { 239 return has_optional_value(val.get()); 240 } 241 }; 242 243 /////////////////////////////////////////////////////////////////////////// 244 template <typename T, int N, typename Attribute, typename Domain> 245 struct transform_attribute< 246 fusion::extension::adt_attribute_proxy<T, N, false> 247 , Attribute 248 , Domain 249 , typename disable_if<is_reference< 250 typename fusion::extension::adt_attribute_proxy<T, N, false>::type 251 > >::type> 252 { 253 typedef Attribute type; 254 255 static Attribute preboost::spirit::traits::transform_attribute256 pre(fusion::extension::adt_attribute_proxy<T, N, false>& val) 257 { 258 return val; 259 } 260 static void postboost::spirit::traits::transform_attribute261 post( 262 fusion::extension::adt_attribute_proxy<T, N, false>& val 263 , Attribute const& attr) 264 { 265 val = attr; 266 } 267 static void failboost::spirit::traits::transform_attribute268 fail(fusion::extension::adt_attribute_proxy<T, N, false>&) 269 { 270 } 271 }; 272 273 template < 274 typename T, int N, bool Const, typename Attribute, typename Domain> 275 struct transform_attribute< 276 fusion::extension::adt_attribute_proxy<T, N, Const> 277 , Attribute 278 , Domain 279 , typename enable_if<is_reference< 280 typename fusion::extension::adt_attribute_proxy< 281 T, N, Const 282 >::type 283 > >::type> 284 { 285 typedef Attribute& type; 286 287 static Attribute& preboost::spirit::traits::transform_attribute288 pre(fusion::extension::adt_attribute_proxy<T, N, Const>& val) 289 { 290 return val; 291 } 292 static void postboost::spirit::traits::transform_attribute293 post( 294 fusion::extension::adt_attribute_proxy<T, N, Const>& 295 , Attribute const&) 296 { 297 } 298 static void failboost::spirit::traits::transform_attribute299 fail(fusion::extension::adt_attribute_proxy<T, N, Const>&) 300 { 301 } 302 }; 303 304 template <typename T, int N, bool Const> 305 struct clear_value<fusion::extension::adt_attribute_proxy<T, N, Const> > 306 { callboost::spirit::traits::clear_value307 static void call( 308 fusion::extension::adt_attribute_proxy<T, N, Const>& val) 309 { 310 typedef typename 311 fusion::extension::adt_attribute_proxy<T, N, Const>::type 312 type; 313 clear(type(val)); 314 } 315 }; 316 317 template <typename T, int N, bool Const> 318 struct attribute_size<fusion::extension::adt_attribute_proxy<T, N, Const> > 319 { 320 typedef typename remove_const< 321 typename remove_reference< 322 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 323 >::type 324 >::type embedded_type; 325 326 typedef typename attribute_size<embedded_type>::type type; 327 328 static type callboost::spirit::traits::attribute_size329 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 330 { 331 return attribute_size<embedded_type>::call(val.get()); 332 } 333 }; 334 335 /////////////////////////////////////////////////////////////////////////// 336 // customization point specializations for numeric generators 337 template <typename T, int N, bool Const> 338 struct absolute_value<fusion::extension::adt_attribute_proxy<T, N, Const> > 339 { 340 typedef typename 341 fusion::extension::adt_attribute_proxy<T, N, Const>::type 342 type; 343 344 static type callboost::spirit::traits::absolute_value345 call (fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 346 { 347 return get_absolute_value(val.get()); 348 } 349 }; 350 351 template <typename T, int N, bool Const> 352 struct is_negative<fusion::extension::adt_attribute_proxy<T, N, Const> > 353 { 354 static bool callboost::spirit::traits::is_negative355 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 356 { 357 return test_negative(val.get()); 358 } 359 }; 360 361 template <typename T, int N, bool Const> 362 struct is_zero<fusion::extension::adt_attribute_proxy<T, N, Const> > 363 { 364 static bool callboost::spirit::traits::is_zero365 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 366 { 367 return test_zero(val.get()); 368 } 369 }; 370 371 template <typename T, int N, bool Const> 372 struct is_nan<fusion::extension::adt_attribute_proxy<T, N, Const> > 373 { 374 static bool callboost::spirit::traits::is_nan375 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 376 { 377 return test_nan(val.get()); 378 } 379 }; 380 381 template <typename T, int N, bool Const> 382 struct is_infinite<fusion::extension::adt_attribute_proxy<T, N, Const> > 383 { 384 static bool callboost::spirit::traits::is_infinite385 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 386 { 387 return test_infinite(val.get()); 388 } 389 }; 390 }}} 391 392 /////////////////////////////////////////////////////////////////////////////// 393 namespace boost { namespace spirit { namespace result_of 394 { 395 template <typename T, int N, bool Const> 396 struct optional_value<fusion::extension::adt_attribute_proxy<T, N, Const> > 397 : result_of::optional_value< 398 typename remove_const< 399 typename remove_reference< 400 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 401 >::type 402 >::type> 403 {}; 404 }}} 405 406 #endif 407