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 197 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 198 get_return_type; 199 typedef typename remove_const< 200 typename remove_reference< 201 get_return_type 202 >::type 203 >::type embedded_type; 204 typedef 205 typename spirit::result_of::extract_from<Exposed, embedded_type>::type 206 extracted_type; 207 208 // If adt_attribute_proxy returned a value we must pass the attribute 209 // by value, otherwise we will end up with a reference to a temporary 210 // that will expire out of scope of the function call. 211 typedef typename mpl::if_c<is_reference<get_return_type>::value 212 , extracted_type 213 , typename remove_reference<extracted_type>::type 214 >::type type; 215 216 template <typename Context> 217 static type callboost::spirit::traits::extract_from_attribute218 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val, Context& ctx) 219 { 220 return extract_from<Exposed>(val.get(), ctx); 221 } 222 }; 223 224 /////////////////////////////////////////////////////////////////////////// 225 template <typename T, int N, bool Const> 226 struct attribute_type<fusion::extension::adt_attribute_proxy<T, N, Const> > 227 : fusion::extension::adt_attribute_proxy<T, N, Const> 228 {}; 229 230 /////////////////////////////////////////////////////////////////////////// 231 template <typename T, int N, bool Const> 232 struct optional_attribute< 233 fusion::extension::adt_attribute_proxy<T, N, Const> > 234 { 235 typedef typename result_of::optional_value< 236 typename remove_reference< 237 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 238 >::type 239 >::type type; 240 241 static type callboost::spirit::traits::optional_attribute242 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 243 { 244 return optional_value(val.get()); 245 } 246 247 static bool is_validboost::spirit::traits::optional_attribute248 is_valid(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 249 { 250 return has_optional_value(val.get()); 251 } 252 }; 253 254 /////////////////////////////////////////////////////////////////////////// 255 template <typename T, int N, typename Attribute, typename Domain> 256 struct transform_attribute< 257 fusion::extension::adt_attribute_proxy<T, N, false> 258 , Attribute 259 , Domain 260 , typename disable_if<is_reference< 261 typename fusion::extension::adt_attribute_proxy<T, N, false>::type 262 > >::type> 263 { 264 typedef Attribute type; 265 266 static Attribute preboost::spirit::traits::transform_attribute267 pre(fusion::extension::adt_attribute_proxy<T, N, false>& val) 268 { 269 return val; 270 } 271 static void postboost::spirit::traits::transform_attribute272 post( 273 fusion::extension::adt_attribute_proxy<T, N, false>& val 274 , Attribute const& attr) 275 { 276 val = attr; 277 } 278 static void failboost::spirit::traits::transform_attribute279 fail(fusion::extension::adt_attribute_proxy<T, N, false>&) 280 { 281 } 282 }; 283 284 template < 285 typename T, int N, bool Const, typename Attribute, typename Domain> 286 struct transform_attribute< 287 fusion::extension::adt_attribute_proxy<T, N, Const> 288 , Attribute 289 , Domain 290 , typename enable_if<is_reference< 291 typename fusion::extension::adt_attribute_proxy< 292 T, N, Const 293 >::type 294 > >::type> 295 { 296 typedef Attribute& type; 297 298 static Attribute& preboost::spirit::traits::transform_attribute299 pre(fusion::extension::adt_attribute_proxy<T, N, Const>& val) 300 { 301 return val; 302 } 303 static void postboost::spirit::traits::transform_attribute304 post( 305 fusion::extension::adt_attribute_proxy<T, N, Const>& 306 , Attribute const&) 307 { 308 } 309 static void failboost::spirit::traits::transform_attribute310 fail(fusion::extension::adt_attribute_proxy<T, N, Const>&) 311 { 312 } 313 }; 314 315 template <typename T, int N, bool Const> 316 struct clear_value<fusion::extension::adt_attribute_proxy<T, N, Const> > 317 { callboost::spirit::traits::clear_value318 static void call( 319 fusion::extension::adt_attribute_proxy<T, N, Const>& val) 320 { 321 typedef typename 322 fusion::extension::adt_attribute_proxy<T, N, Const>::type 323 type; 324 clear(type(val)); 325 } 326 }; 327 328 template <typename T, int N, bool Const> 329 struct attribute_size<fusion::extension::adt_attribute_proxy<T, N, Const> > 330 { 331 typedef typename remove_const< 332 typename remove_reference< 333 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 334 >::type 335 >::type embedded_type; 336 337 typedef typename attribute_size<embedded_type>::type type; 338 339 static type callboost::spirit::traits::attribute_size340 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 341 { 342 return attribute_size<embedded_type>::call(val.get()); 343 } 344 }; 345 346 /////////////////////////////////////////////////////////////////////////// 347 // customization point specializations for numeric generators 348 template <typename T, int N, bool Const> 349 struct absolute_value<fusion::extension::adt_attribute_proxy<T, N, Const> > 350 { 351 typedef typename 352 fusion::extension::adt_attribute_proxy<T, N, Const>::type 353 type; 354 355 static type callboost::spirit::traits::absolute_value356 call (fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 357 { 358 return get_absolute_value(val.get()); 359 } 360 }; 361 362 template <typename T, int N, bool Const> 363 struct is_negative<fusion::extension::adt_attribute_proxy<T, N, Const> > 364 { 365 static bool callboost::spirit::traits::is_negative366 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 367 { 368 return test_negative(val.get()); 369 } 370 }; 371 372 template <typename T, int N, bool Const> 373 struct is_zero<fusion::extension::adt_attribute_proxy<T, N, Const> > 374 { 375 static bool callboost::spirit::traits::is_zero376 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 377 { 378 return test_zero(val.get()); 379 } 380 }; 381 382 template <typename T, int N, bool Const> 383 struct is_nan<fusion::extension::adt_attribute_proxy<T, N, Const> > 384 { 385 static bool callboost::spirit::traits::is_nan386 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 387 { 388 return test_nan(val.get()); 389 } 390 }; 391 392 template <typename T, int N, bool Const> 393 struct is_infinite<fusion::extension::adt_attribute_proxy<T, N, Const> > 394 { 395 static bool callboost::spirit::traits::is_infinite396 call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) 397 { 398 return test_infinite(val.get()); 399 } 400 }; 401 }}} 402 403 /////////////////////////////////////////////////////////////////////////////// 404 namespace boost { namespace spirit { namespace result_of 405 { 406 template <typename T, int N, bool Const> 407 struct optional_value<fusion::extension::adt_attribute_proxy<T, N, Const> > 408 : result_of::optional_value< 409 typename remove_const< 410 typename remove_reference< 411 typename fusion::extension::adt_attribute_proxy<T, N, Const>::type 412 >::type 413 >::type> 414 {}; 415 }}} 416 417 #endif 418