1/*============================================================================= 2 Copyright (c) 1998-2003 Joel de Guzman 3 http://spirit.sourceforge.net/ 4 5 Use, modification and distribution is subject to the Boost Software 6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 http://www.boost.org/LICENSE_1_0.txt) 8=============================================================================*/ 9#if !defined(BOOST_SPIRIT_MATCH_ATTR_TRAITS_IPP) 10#define BOOST_SPIRIT_MATCH_ATTR_TRAITS_IPP 11 12#include <boost/optional.hpp> 13#include <boost/mpl/bool.hpp> 14#include <boost/mpl/or.hpp> 15#include <boost/type_traits/is_convertible.hpp> 16#include <boost/type_traits/is_same.hpp> 17 18namespace boost { namespace spirit { 19 20BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 21 22namespace impl 23{ 24 template <typename T> 25 struct match_attr_traits 26 { 27 typedef typename 28 boost::optional<T>::reference_const_type 29 const_reference; 30 31 // case where src *IS* convertible to T (dest) 32 template <typename T2> 33 static void 34 convert(boost::optional<T>& dest, T2 const& src, mpl::true_) 35 { 36 dest.reset(src); 37 } 38 39 // case where src *IS NOT* convertible to T (dest) 40 template <typename T2> 41 static void 42 convert(boost::optional<T>& dest, T2 const& /*src*/, mpl::false_) 43 { 44 dest.reset(); 45 } 46 47 static void 48 convert(boost::optional<T>& dest, nil_t/*src*/) 49 { 50 dest.reset(); 51 } 52 53 template <typename T2> 54 static void 55 convert(boost::optional<T>& dest, T2 const& src) 56 { 57 convert(dest, src, is_convertible<T2, T>()); 58 } 59 60 template <typename OtherMatchT> 61 static void 62 copy(boost::optional<T>& dest, OtherMatchT const& src) 63 { 64 if (src.has_valid_attribute()) 65 convert(dest, src.value()); 66 } 67 68 template <typename OtherMatchT> 69 static void 70 assign(boost::optional<T>& dest, OtherMatchT const& src) 71 { 72 if (src.has_valid_attribute()) 73 convert(dest, src.value()); 74 else 75 dest.reset(); 76 } 77 78 // T is not reference 79 template <typename ValueT> 80 static void 81 set_value(boost::optional<T>& dest, ValueT const& val, mpl::false_) 82 { 83 dest.reset(val); 84 } 85 86 // T is a reference 87 template <typename ValueT> 88 static void 89 set_value(boost::optional<T>& dest, ValueT const& val, mpl::true_) 90 { 91 dest.get() = val; 92 } 93 }; 94 95} 96 97BOOST_SPIRIT_CLASSIC_NAMESPACE_END 98 99}} // namespace boost::spirit::impl 100 101#endif 102 103