map_assign_code_gen.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. #include <boost/assign/list_of.hpp>
  8. #include <map>
  9. #include <iostream>
  10. template<typename Key, typename Value, typename Allocator>
  11. struct map_list_of_transform
  12. {
  13. template<typename Fn, typename Key2, typename Value2>
  14. auto operator()(
  15. boost::yap::expr_tag<boost::yap::expr_kind::call>,
  16. Fn const & fn,
  17. Key2 && key,
  18. Value2 && value)
  19. {
  20. boost::yap::transform(
  21. boost::yap::as_expr<boost::yap::minimal_expr>(fn), *this);
  22. map.emplace(
  23. Key{std::forward<Key2 &&>(key)},
  24. Value{std::forward<Value2 &&>(value)});
  25. return 0;
  26. }
  27. std::map<Key, Value, Allocator> map;
  28. };
  29. template<boost::yap::expr_kind Kind, typename Tuple>
  30. struct map_list_of_expr
  31. {
  32. static boost::yap::expr_kind const kind = Kind;
  33. Tuple elements;
  34. template<typename Key, typename Value, typename Allocator>
  35. operator std::map<Key, Value, Allocator>() const
  36. {
  37. map_list_of_transform<Key, Value, Allocator> transform;
  38. boost::yap::transform(*this, transform);
  39. return transform.map;
  40. }
  41. BOOST_YAP_USER_CALL_OPERATOR(::map_list_of_expr)
  42. };
  43. struct map_list_of_tag
  44. {};
  45. auto map_list_of =
  46. boost::yap::make_terminal<map_list_of_expr>(map_list_of_tag{});
  47. #if __GNUC__ || __clang__
  48. #define NOINLINE __attribute__((noinline))
  49. #else
  50. #define NOINLINE
  51. #endif
  52. NOINLINE std::map<std::string, int> make_map_with_boost_yap()
  53. {
  54. return map_list_of("<", 1)("<=", 2)(">", 3)(">=", 4)("=", 5)("<>", 6);
  55. }
  56. NOINLINE std::map<std::string, int> make_map_with_boost_assign()
  57. {
  58. return boost::assign::map_list_of("<", 1)("<=", 2)(">", 3)(">=", 4)("=", 5)(
  59. "<>", 6);
  60. }
  61. NOINLINE std::map<std::string, int> make_map_manually()
  62. {
  63. std::map<std::string, int> retval;
  64. retval.emplace("<", 1);
  65. retval.emplace("<=", 2);
  66. retval.emplace(">", 3);
  67. retval.emplace(">=", 4);
  68. retval.emplace("=", 5);
  69. retval.emplace("<>", 6);
  70. return retval;
  71. }
  72. NOINLINE std::map<std::string, int> make_map_inializer_list()
  73. {
  74. std::map<std::string, int> retval = {
  75. {"<", 1}, {"<=", 2}, {">", 3}, {">=", 4}, {"=", 5}, {"<>", 6}};
  76. return retval;
  77. }
  78. int main()
  79. {
  80. {
  81. std::map<std::string, int> op = make_map_with_boost_yap();
  82. std::cout << "\"<\" --> " << op["<"] << std::endl;
  83. std::cout << "\"<=\" --> " << op["<="] << std::endl;
  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. }
  89. {
  90. std::map<std::string, int> op = make_map_with_boost_assign();
  91. std::cout << "\"<\" --> " << op["<"] << std::endl;
  92. std::cout << "\"<=\" --> " << op["<="] << std::endl;
  93. std::cout << "\">\" --> " << op[">"] << std::endl;
  94. std::cout << "\">=\" --> " << op[">="] << std::endl;
  95. std::cout << "\"=\" --> " << op["="] << std::endl;
  96. std::cout << "\"<>\" --> " << op["<>"] << std::endl;
  97. }
  98. {
  99. std::map<std::string, int> op = make_map_manually();
  100. std::cout << "\"<\" --> " << op["<"] << std::endl;
  101. std::cout << "\"<=\" --> " << op["<="] << std::endl;
  102. std::cout << "\">\" --> " << op[">"] << std::endl;
  103. std::cout << "\">=\" --> " << op[">="] << std::endl;
  104. std::cout << "\"=\" --> " << op["="] << std::endl;
  105. std::cout << "\"<>\" --> " << op["<>"] << std::endl;
  106. }
  107. {
  108. std::map<std::string, int> op = make_map_inializer_list();
  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. std::cout << "\"=\" --> " << op["="] << std::endl;
  114. std::cout << "\"<>\" --> " << op["<>"] << std::endl;
  115. }
  116. return 0;
  117. }