1 /*============================================================================= 2 Copyright (c) 2001-2014 Joel de Guzman 3 http://spirit.sourceforge.net/ 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 =============================================================================*/ 8 #if !defined(BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM) 9 #define BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM 10 11 #include <boost/spirit/home/x3/support/unused.hpp> 12 #include <boost/mpl/identity.hpp> 13 14 namespace boost { namespace spirit { namespace x3 15 { 16 template <typename ID, typename T, typename Next = unused_type> 17 struct context 18 { contextboost::spirit::x3::context19 context(T& val, Next const& next) 20 : val(val), next(next) {} 21 getboost::spirit::x3::context22 T& get(mpl::identity<ID>) const 23 { 24 return val; 25 } 26 27 template <typename ID_> getboost::spirit::x3::context28 decltype(auto) get(ID_ id) const 29 { 30 return next.get(id); 31 } 32 33 T& val; 34 Next const& next; 35 }; 36 37 template <typename ID, typename T> 38 struct context<ID, T, unused_type> 39 { contextboost::spirit::x3::context40 context(T& val) 41 : val(val) {} 42 contextboost::spirit::x3::context43 context(T& val, unused_type) 44 : val(val) {} 45 getboost::spirit::x3::context46 T& get(mpl::identity<ID>) const 47 { 48 return val; 49 } 50 51 template <typename ID_> getboost::spirit::x3::context52 unused_type get(ID_) const 53 { 54 return {}; 55 } 56 57 T& val; 58 }; 59 60 template <typename Tag, typename Context> get(Context const & context)61 inline decltype(auto) get(Context const& context) 62 { 63 return context.get(mpl::identity<Tag>()); 64 } 65 66 template <typename ID, typename T, typename Next> make_context(T & val,Next const & next)67 inline context<ID, T, Next> make_context(T& val, Next const& next) 68 { 69 return { val, next }; 70 } 71 72 template <typename ID, typename T> make_context(T & val)73 inline context<ID, T> make_context(T& val) 74 { 75 return { val }; 76 } 77 78 namespace detail 79 { 80 template <typename ID, typename T, typename Next, typename FoundVal> 81 inline Next const& make_unique_context(T &,Next const & next,FoundVal &)82 make_unique_context(T& /* val */, Next const& next, FoundVal&) 83 { 84 return next; 85 } 86 87 template <typename ID, typename T, typename Next> 88 inline context<ID, T, Next> make_unique_context(T & val,Next const & next,unused_type)89 make_unique_context(T& val, Next const& next, unused_type) 90 { 91 return { val, next }; 92 } 93 } 94 95 template <typename ID, typename T, typename Next> 96 inline auto make_unique_context(T & val,Next const & next)97 make_unique_context(T& val, Next const& next) 98 { 99 return detail::make_unique_context<ID>(val, next, x3::get<ID>(next)); 100 } 101 }}} 102 103 #endif 104