123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- // Copyright (C) 2016-2018 T. Zachary Laine
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #include <boost/yap/expression.hpp>
- #include <boost/assign/list_of.hpp>
- #include <map>
- #include <iostream>
- template<typename Key, typename Value, typename Allocator>
- struct map_list_of_transform
- {
- template<typename Fn, typename Key2, typename Value2>
- auto operator()(
- boost::yap::expr_tag<boost::yap::expr_kind::call>,
- Fn const & fn,
- Key2 && key,
- Value2 && value)
- {
- boost::yap::transform(
- boost::yap::as_expr<boost::yap::minimal_expr>(fn), *this);
- map.emplace(
- Key{std::forward<Key2 &&>(key)},
- Value{std::forward<Value2 &&>(value)});
- return 0;
- }
- std::map<Key, Value, Allocator> map;
- };
- template<boost::yap::expr_kind Kind, typename Tuple>
- struct map_list_of_expr
- {
- static boost::yap::expr_kind const kind = Kind;
- Tuple elements;
- template<typename Key, typename Value, typename Allocator>
- operator std::map<Key, Value, Allocator>() const
- {
- map_list_of_transform<Key, Value, Allocator> transform;
- boost::yap::transform(*this, transform);
- return transform.map;
- }
- BOOST_YAP_USER_CALL_OPERATOR(::map_list_of_expr)
- };
- struct map_list_of_tag
- {};
- auto map_list_of =
- boost::yap::make_terminal<map_list_of_expr>(map_list_of_tag{});
- #if __GNUC__ || __clang__
- #define NOINLINE __attribute__((noinline))
- #else
- #define NOINLINE
- #endif
- NOINLINE std::map<std::string, int> make_map_with_boost_yap()
- {
- return map_list_of("<", 1)("<=", 2)(">", 3)(">=", 4)("=", 5)("<>", 6);
- }
- NOINLINE std::map<std::string, int> make_map_with_boost_assign()
- {
- return boost::assign::map_list_of("<", 1)("<=", 2)(">", 3)(">=", 4)("=", 5)(
- "<>", 6);
- }
- NOINLINE std::map<std::string, int> make_map_manually()
- {
- std::map<std::string, int> retval;
- retval.emplace("<", 1);
- retval.emplace("<=", 2);
- retval.emplace(">", 3);
- retval.emplace(">=", 4);
- retval.emplace("=", 5);
- retval.emplace("<>", 6);
- return retval;
- }
- NOINLINE std::map<std::string, int> make_map_inializer_list()
- {
- std::map<std::string, int> retval = {
- {"<", 1}, {"<=", 2}, {">", 3}, {">=", 4}, {"=", 5}, {"<>", 6}};
- return retval;
- }
- int main()
- {
- {
- std::map<std::string, int> op = make_map_with_boost_yap();
- std::cout << "\"<\" --> " << op["<"] << std::endl;
- std::cout << "\"<=\" --> " << op["<="] << std::endl;
- std::cout << "\">\" --> " << op[">"] << std::endl;
- std::cout << "\">=\" --> " << op[">="] << std::endl;
- std::cout << "\"=\" --> " << op["="] << std::endl;
- std::cout << "\"<>\" --> " << op["<>"] << std::endl;
- }
- {
- std::map<std::string, int> op = make_map_with_boost_assign();
- std::cout << "\"<\" --> " << op["<"] << std::endl;
- std::cout << "\"<=\" --> " << op["<="] << std::endl;
- std::cout << "\">\" --> " << op[">"] << std::endl;
- std::cout << "\">=\" --> " << op[">="] << std::endl;
- std::cout << "\"=\" --> " << op["="] << std::endl;
- std::cout << "\"<>\" --> " << op["<>"] << std::endl;
- }
- {
- std::map<std::string, int> op = make_map_manually();
- std::cout << "\"<\" --> " << op["<"] << std::endl;
- std::cout << "\"<=\" --> " << op["<="] << std::endl;
- std::cout << "\">\" --> " << op[">"] << std::endl;
- std::cout << "\">=\" --> " << op[">="] << std::endl;
- std::cout << "\"=\" --> " << op["="] << std::endl;
- std::cout << "\"<>\" --> " << op["<>"] << std::endl;
- }
- {
- std::map<std::string, int> op = make_map_inializer_list();
- std::cout << "\"<\" --> " << op["<"] << std::endl;
- std::cout << "\"<=\" --> " << op["<="] << std::endl;
- std::cout << "\">\" --> " << op[">"] << std::endl;
- std::cout << "\">=\" --> " << op[">="] << std::endl;
- std::cout << "\"=\" --> " << op["="] << std::endl;
- std::cout << "\"<>\" --> " << op["<>"] << std::endl;
- }
- return 0;
- }
|