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