1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file literal.hpp
3 /// The literal\<\> terminal wrapper, and the proto::lit() function for
4 /// creating literal\<\> wrappers.
5 //
6 //  Copyright 2008 Eric Niebler. Distributed under the Boost
7 //  Software License, Version 1.0. (See accompanying file
8 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 
10 #ifndef BOOST_PROTO_LITERAL_HPP_EAN_01_03_2007
11 #define BOOST_PROTO_LITERAL_HPP_EAN_01_03_2007
12 
13 #include <boost/config.hpp>
14 #include <boost/proto/proto_fwd.hpp>
15 #include <boost/proto/expr.hpp>
16 #include <boost/proto/traits.hpp>
17 #include <boost/proto/extends.hpp>
18 
19 namespace boost { namespace proto
20 {
21     namespace utility
22     {
23         /// \brief A simple wrapper for a terminal, provided for
24         /// ease of use.
25         ///
26         /// A simple wrapper for a terminal, provided for
27         /// ease of use. In all cases, <tt>literal\<X\> l(x);</tt>
28         /// is equivalent to <tt>terminal\<X\>::type l = {x};</tt>.
29         ///
30         /// The \c Domain template parameter defaults to
31         /// \c proto::default_domain.
32         template<
33             typename T
34           , typename Domain // = default_domain
35         >
36         struct literal
37           : extends<basic_expr<tag::terminal, term<T>, 0>, literal<T, Domain>, Domain>
38         {
39         private:
40             typedef basic_expr<tag::terminal, term<T>, 0> terminal_type;
41             typedef extends<terminal_type, literal<T, Domain>, Domain> base_type;
42             typedef literal<T, Domain> literal_t;
43 
44         public:
45             typedef typename detail::term_traits<T>::value_type       value_type;
46             typedef typename detail::term_traits<T>::reference        reference;
47             typedef typename detail::term_traits<T>::const_reference  const_reference;
48 
literalboost::proto::utility::literal49             literal()
50               : base_type(terminal_type::make(T()))
51             {}
52 
53             template<typename U>
literalboost::proto::utility::literal54             literal(U &u)
55               : base_type(terminal_type::make(u))
56             {}
57 
58             template<typename U>
literalboost::proto::utility::literal59             literal(U const &u)
60               : base_type(terminal_type::make(u))
61             {}
62 
63             template<typename U>
literalboost::proto::utility::literal64             literal(literal<U, Domain> const &u)
65               : base_type(terminal_type::make(u.get()))
66             {}
67 
BOOST_PROTO_EXTENDS_USING_ASSIGNboost::proto::utility::literal68             BOOST_PROTO_EXTENDS_USING_ASSIGN(literal_t)
69 
70             reference get()
71             {
72                 return proto::value(*this);
73             }
74 
getboost::proto::utility::literal75             const_reference get() const
76             {
77                 return proto::value(*this);
78             }
79         };
80     }
81 
82     /// \brief A helper function for creating a \c literal\<\> wrapper.
83     /// \param t The object to wrap.
84     /// \return literal\<T &\>(t)
85     /// \attention The returned value holds the argument by reference.
86     /// \throw nothrow
87     template<typename T>
lit(T & t)88     inline literal<T &> const lit(T &t)
89     {
90         return literal<T &>(t);
91     }
92 
93     /// \overload
94     ///
95     template<typename T>
lit(T const & t)96     inline literal<T const &> const lit(T const &t)
97     {
98         #ifdef BOOST_MSVC
99         #pragma warning(push)
100         #pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored
101         #endif
102 
103         return literal<T const &>(t);
104 
105         #ifdef BOOST_MSVC
106         #pragma warning(pop)
107         #endif
108     }
109 
110 }}
111 
112 #endif
113