143beb91de
Fixes #22. Fixes #68.
150 lines
4.1 KiB
C++
150 lines
4.1 KiB
C++
// 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;
|
|
}
|