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