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