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