Release 1.39.0
[boost.git] / Boost_1_39_0 / boost / spirit / home / support / detail / values.hpp
blobfb1796c21a4f7075691a2c704d535c51b4c343f4
1 /*=============================================================================
2 Copyright (c) 2001-2007 Joel de Guzman
3 Copyright (c) 2001-2009 Hartmut Kaiser
4 http://spirit.sourceforge.net/
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 #if !defined(BOOST_SPIRIT_VALUES_JAN_07_2007_0802PM)
10 #define BOOST_SPIRIT_VALUES_JAN_07_2007_0802PM
12 #include <boost/fusion/include/is_sequence.hpp>
13 #include <boost/fusion/include/vector.hpp>
14 #include <boost/spirit/home/support/unused.hpp>
15 #include <boost/utility/enable_if.hpp>
16 #include <boost/mpl/bool.hpp>
17 #include <boost/mpl/and.hpp>
18 #include <boost/variant.hpp>
20 namespace boost { namespace spirit { namespace detail
22 template <typename T>
23 struct not_is_variant
24 : mpl::true_ {};
26 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
27 struct not_is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
28 : mpl::false_ {};
30 ///////////////////////////////////////////////////////////////////////////
31 // All parsers and generators have specific attribute or parameter types.
32 // Spirit parsers are passed an attribute and Spirit generators
33 // are passed a parameter; these are either references to the expected
34 // type, or an unused_type -- to flag that we do not care about the
35 // attribute/parameter. For semantic actions, however, we need to have a
36 // real value to pass to the semantic action. If the client did not
37 // provide one, we will have to synthesize the value. This class
38 // takes care of that.
39 ///////////////////////////////////////////////////////////////////////////
40 template <typename ValueType>
41 struct make_value
43 static ValueType call(unused_type)
45 return ValueType(); // synthesize the attribute/parameter
48 template <typename T>
49 static T& call(T& value)
51 return value; // just pass the one provided
54 template <typename T>
55 static T const& call(T const& value)
57 return value; // just pass the one provided
61 template <typename ValueType>
62 struct make_value<ValueType&> : make_value<ValueType>
66 template <>
67 struct make_value<unused_type>
69 static unused_type call(unused_type)
71 return unused;
75 ///////////////////////////////////////////////////////////////////////////
76 // pass_value determines how we pass attributes and parameters to semantic
77 // actions. Basically, all SAs receive the arguments in a tuple. So, if
78 // the argument to be passed is not a tuple, wrap it in one.
79 ///////////////////////////////////////////////////////////////////////////
80 template <typename ValueType>
81 struct pass_value
83 typedef
84 mpl::and_<
85 fusion::traits::is_sequence<ValueType>
86 , detail::not_is_variant<ValueType>
88 is_sequence;
90 typedef typename
91 mpl::if_<
92 is_sequence
93 , ValueType&
94 , fusion::vector<ValueType&> const
95 >::type
96 type;
98 static ValueType&
99 call(ValueType& arg, mpl::true_)
101 // arg is a fusion sequence (except a variant) return it as-is.
102 return arg;
105 static fusion::vector<ValueType&> const
106 call(ValueType& seq, mpl::false_)
108 // arg is a not fusion sequence wrap it in a fusion::vector.
109 return fusion::vector<ValueType&>(seq);
112 static type
113 call(ValueType& arg)
115 return call(arg, is_sequence());
120 #endif