map_assign.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. #include <map>
  9. #include <iostream>
  10. // This transform applies all the call-subexpressions in a map_list_of
  11. // expression (a nested chain of call operations) as a side effect; the
  12. // expression returned by the transform is ignored.
  13. template <typename Key, typename Value, typename Allocator>
  14. struct map_list_of_transform
  15. {
  16. template <typename Fn, typename Key2, typename Value2>
  17. auto operator() (boost::yap::expr_tag<boost::yap::expr_kind::call>,
  18. Fn const & fn, Key2 && key, Value2 && value)
  19. {
  20. // Recurse into the function subexpression. Remember, transform()
  21. // walks the nodes in an expression tree looking for matches. Once it
  22. // finds a match, it is finished with that matching subtree. So
  23. // without this recursive call, only the top-level call expression is
  24. // matched by transform().
  25. boost::yap::transform(
  26. boost::yap::as_expr<boost::yap::minimal_expr>(fn), *this);
  27. map.emplace(
  28. std::forward<Key2 &&>(key),
  29. std::forward<Value2 &&>(value)
  30. );
  31. // All we care about are the side effects of this transform, so we can
  32. // return any old thing here.
  33. return 0;
  34. }
  35. std::map<Key, Value, Allocator> & map;
  36. };
  37. // A custom expression template type for map_list_of expressions. We only
  38. // need support for the call operator and an implicit conversion to a
  39. // std::map.
  40. template <boost::yap::expr_kind Kind, typename Tuple>
  41. struct map_list_of_expr
  42. {
  43. static boost::yap::expr_kind const kind = Kind;
  44. Tuple elements;
  45. template <typename Key, typename Value, typename Allocator>
  46. operator std::map<Key, Value, Allocator> () const
  47. {
  48. std::map<Key, Value, Allocator> retval;
  49. map_list_of_transform<Key, Value, Allocator> transform{retval};
  50. boost::yap::transform(*this, transform);
  51. return retval;
  52. }
  53. BOOST_YAP_USER_CALL_OPERATOR_N(::map_list_of_expr, 2)
  54. };
  55. // A tag type for creating the map_list_of function terminal.
  56. struct map_list_of_tag {};
  57. auto map_list_of = boost::yap::make_terminal<map_list_of_expr>(map_list_of_tag{});
  58. int main()
  59. {
  60. // Initialize a map:
  61. std::map<std::string, int> op =
  62. map_list_of
  63. ("<", 1)
  64. ("<=",2)
  65. (">", 3)
  66. (">=",4)
  67. ("=", 5)
  68. ("<>",6)
  69. ;
  70. std::cout << "\"<\" --> " << op["<"] << std::endl;
  71. std::cout << "\"<=\" --> " << op["<="] << std::endl;
  72. std::cout << "\">\" --> " << op[">"] << std::endl;
  73. std::cout << "\">=\" --> " << op[">="] << std::endl;
  74. std::cout << "\"=\" --> " << op["="] << std::endl;
  75. std::cout << "\"<>\" --> " << op["<>"] << std::endl;
  76. return 0;
  77. }
  78. //]