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 #ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
54             literal(literal const &) = default;
55 #endif
56 
57             template<typename U>
literalboost::proto::utility::literal58             literal(U &u)
59               : base_type(terminal_type::make(u))
60             {}
61 
62             template<typename U>
literalboost::proto::utility::literal63             literal(U const &u)
64               : base_type(terminal_type::make(u))
65             {}
66 
67             template<typename U>
literalboost::proto::utility::literal68             literal(literal<U, Domain> const &u)
69               : base_type(terminal_type::make(u.get()))
70             {}
71 
BOOST_PROTO_EXTENDS_USING_ASSIGNboost::proto::utility::literal72             BOOST_PROTO_EXTENDS_USING_ASSIGN(literal_t)
73 
74             reference get()
75             {
76                 return proto::value(*this);
77             }
78 
getboost::proto::utility::literal79             const_reference get() const
80             {
81                 return proto::value(*this);
82             }
83         };
84     }
85 
86     /// \brief A helper function for creating a \c literal\<\> wrapper.
87     /// \param t The object to wrap.
88     /// \return literal\<T &\>(t)
89     /// \attention The returned value holds the argument by reference.
90     /// \throw nothrow
91     template<typename T>
lit(T & t)92     inline literal<T &> const lit(T &t)
93     {
94         return literal<T &>(t);
95     }
96 
97     /// \overload
98     ///
99     template<typename T>
lit(T const & t)100     inline literal<T const &> const lit(T const &t)
101     {
102         #ifdef BOOST_MSVC
103         #pragma warning(push)
104         #pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored
105         #endif
106 
107         return literal<T const &>(t);
108 
109         #ifdef BOOST_MSVC
110         #pragma warning(pop)
111         #endif
112     }
113 
114 }}
115 
116 #endif
117