• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2016-2018 T. Zachary Laine
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //[ map_assign
7 #include <boost/yap/algorithm.hpp>
8 
9 #include <map>
10 #include <iostream>
11 
12 
13 // This transform applies all the call-subexpressions in a map_list_of
14 // expression (a nested chain of call operations) as a side effect; the
15 // expression returned by the transform is ignored.
16 template <typename Key, typename Value, typename Allocator>
17 struct map_list_of_transform
18 {
19     template <typename Fn, typename Key2, typename Value2>
operator ()map_list_of_transform20     auto operator() (boost::yap::expr_tag<boost::yap::expr_kind::call>,
21                      Fn const & fn, Key2 && key, Value2 && value)
22     {
23         // Recurse into the function subexpression.  Remember, transform()
24         // walks the nodes in an expression tree looking for matches.  Once it
25         // finds a match, it is finished with that matching subtree.  So
26         // without this recursive call, only the top-level call expression is
27         // matched by transform().
28         boost::yap::transform(
29             boost::yap::as_expr<boost::yap::minimal_expr>(fn), *this);
30         map.emplace(
31             std::forward<Key2 &&>(key),
32             std::forward<Value2 &&>(value)
33         );
34         // All we care about are the side effects of this transform, so we can
35         // return any old thing here.
36         return 0;
37     }
38 
39     std::map<Key, Value, Allocator> & map;
40 };
41 
42 
43 // A custom expression template type for map_list_of expressions.  We only
44 // need support for the call operator and an implicit conversion to a
45 // std::map.
46 template <boost::yap::expr_kind Kind, typename Tuple>
47 struct map_list_of_expr
48 {
49     static boost::yap::expr_kind const kind = Kind;
50 
51     Tuple elements;
52 
53     template <typename Key, typename Value, typename Allocator>
operator std::map<Key,Value,Allocator>map_list_of_expr54     operator std::map<Key, Value, Allocator> () const
55     {
56         std::map<Key, Value, Allocator> retval;
57         map_list_of_transform<Key, Value, Allocator> transform{retval};
58         boost::yap::transform(*this, transform);
59         return retval;
60     }
61 
62     BOOST_YAP_USER_CALL_OPERATOR_N(::map_list_of_expr, 2)
63 };
64 
65 // A tag type for creating the map_list_of function terminal.
66 struct map_list_of_tag {};
67 
68 auto map_list_of = boost::yap::make_terminal<map_list_of_expr>(map_list_of_tag{});
69 
70 
main()71 int main()
72 {
73     // Initialize a map:
74     std::map<std::string, int> op =
75         map_list_of
76             ("<", 1)
77             ("<=",2)
78             (">", 3)
79             (">=",4)
80             ("=", 5)
81             ("<>",6)
82         ;
83 
84     std::cout << "\"<\"  --> " << op["<"] << std::endl;
85     std::cout << "\"<=\" --> " << op["<="] << std::endl;
86     std::cout << "\">\"  --> " << op[">"] << std::endl;
87     std::cout << "\">=\" --> " << op[">="] << std::endl;
88     std::cout << "\"=\"  --> " << op["="] << std::endl;
89     std::cout << "\"<>\" --> " << op["<>"] << std::endl;
90 
91     return 0;
92 }
93 //]
94