• 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 #include <boost/yap/expression.hpp>
7 
8 #include <boost/assign/list_of.hpp>
9 
10 #include <map>
11 #include <iostream>
12 
13 
14 template<typename Key, typename Value, typename Allocator>
15 struct map_list_of_transform
16 {
17     template<typename Fn, typename Key2, typename Value2>
operator ()map_list_of_transform18     auto operator()(
19         boost::yap::expr_tag<boost::yap::expr_kind::call>,
20         Fn const & fn,
21         Key2 && key,
22         Value2 && value)
23     {
24         boost::yap::transform(
25             boost::yap::as_expr<boost::yap::minimal_expr>(fn), *this);
26         map.emplace(
27             Key{std::forward<Key2 &&>(key)},
28             Value{std::forward<Value2 &&>(value)});
29         return 0;
30     }
31 
32     std::map<Key, Value, Allocator> map;
33 };
34 
35 
36 template<boost::yap::expr_kind Kind, typename Tuple>
37 struct map_list_of_expr
38 {
39     static boost::yap::expr_kind const kind = Kind;
40 
41     Tuple elements;
42 
43     template<typename Key, typename Value, typename Allocator>
operator std::map<Key,Value,Allocator>map_list_of_expr44     operator std::map<Key, Value, Allocator>() const
45     {
46         map_list_of_transform<Key, Value, Allocator> transform;
47         boost::yap::transform(*this, transform);
48         return transform.map;
49     }
50 
51     BOOST_YAP_USER_CALL_OPERATOR(::map_list_of_expr)
52 };
53 
54 struct map_list_of_tag
55 {};
56 
57 auto map_list_of =
58     boost::yap::make_terminal<map_list_of_expr>(map_list_of_tag{});
59 
60 
61 #if __GNUC__ || __clang__
62 #define NOINLINE __attribute__((noinline))
63 #else
64 #define NOINLINE
65 #endif
66 
67 
make_map_with_boost_yap()68 NOINLINE std::map<std::string, int> make_map_with_boost_yap()
69 {
70     return map_list_of("<", 1)("<=", 2)(">", 3)(">=", 4)("=", 5)("<>", 6);
71 }
72 
73 
make_map_with_boost_assign()74 NOINLINE std::map<std::string, int> make_map_with_boost_assign()
75 {
76     return boost::assign::map_list_of("<", 1)("<=", 2)(">", 3)(">=", 4)("=", 5)(
77         "<>", 6);
78 }
79 
80 
make_map_manually()81 NOINLINE std::map<std::string, int> make_map_manually()
82 {
83     std::map<std::string, int> retval;
84     retval.emplace("<", 1);
85     retval.emplace("<=", 2);
86     retval.emplace(">", 3);
87     retval.emplace(">=", 4);
88     retval.emplace("=", 5);
89     retval.emplace("<>", 6);
90     return retval;
91 }
92 
93 
make_map_inializer_list()94 NOINLINE std::map<std::string, int> make_map_inializer_list()
95 {
96     std::map<std::string, int> retval = {
97         {"<", 1}, {"<=", 2}, {">", 3}, {">=", 4}, {"=", 5}, {"<>", 6}};
98     return retval;
99 }
100 
101 
main()102 int main()
103 {
104     {
105         std::map<std::string, int> op = make_map_with_boost_yap();
106 
107         std::cout << "\"<\"  --> " << op["<"] << std::endl;
108         std::cout << "\"<=\" --> " << op["<="] << std::endl;
109         std::cout << "\">\"  --> " << op[">"] << std::endl;
110         std::cout << "\">=\" --> " << op[">="] << std::endl;
111         std::cout << "\"=\"  --> " << op["="] << std::endl;
112         std::cout << "\"<>\" --> " << op["<>"] << std::endl;
113     }
114 
115     {
116         std::map<std::string, int> op = make_map_with_boost_assign();
117 
118         std::cout << "\"<\"  --> " << op["<"] << std::endl;
119         std::cout << "\"<=\" --> " << op["<="] << std::endl;
120         std::cout << "\">\"  --> " << op[">"] << std::endl;
121         std::cout << "\">=\" --> " << op[">="] << std::endl;
122         std::cout << "\"=\"  --> " << op["="] << std::endl;
123         std::cout << "\"<>\" --> " << op["<>"] << std::endl;
124     }
125 
126     {
127         std::map<std::string, int> op = make_map_manually();
128 
129         std::cout << "\"<\"  --> " << op["<"] << std::endl;
130         std::cout << "\"<=\" --> " << op["<="] << std::endl;
131         std::cout << "\">\"  --> " << op[">"] << std::endl;
132         std::cout << "\">=\" --> " << op[">="] << std::endl;
133         std::cout << "\"=\"  --> " << op["="] << std::endl;
134         std::cout << "\"<>\" --> " << op["<>"] << std::endl;
135     }
136 
137     {
138         std::map<std::string, int> op = make_map_inializer_list();
139 
140         std::cout << "\"<\"  --> " << op["<"] << std::endl;
141         std::cout << "\"<=\" --> " << op["<="] << std::endl;
142         std::cout << "\">\"  --> " << op[">"] << std::endl;
143         std::cout << "\">=\" --> " << op[">="] << std::endl;
144         std::cout << "\"=\"  --> " << op["="] << std::endl;
145         std::cout << "\"<>\" --> " << op["<>"] << std::endl;
146     }
147 
148     return 0;
149 }
150