1//[ MapAssign
2// Copyright 2008 Eric Niebler. Distributed under the Boost
3// Software License, Version 1.0. (See accompanying file
4// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5//
6// This is a port of map_list_of() from the Boost.Assign library.
7// It has the advantage of being more efficient at runtime by not
8// building any temporary container that requires dynamic allocation.
9
10#include <map>
11#include <string>
12#include <iostream>
13#include <boost/proto/core.hpp>
14#include <boost/proto/transform.hpp>
15#include <boost/type_traits/add_reference.hpp>
16namespace proto = boost::proto;
17using proto::_;
18
19struct map_list_of_tag
20{};
21
22// A simple callable function object that inserts a
23// (key,value) pair into a map.
24struct insert
25 : proto::callable
26{
27 template<typename Sig>
28 struct result;
29
30 template<typename This, typename Map, typename Key, typename Value>
31 struct result<This(Map, Key, Value)>
32 : boost::add_reference<Map>
33 {};
34
35 template<typename Map, typename Key, typename Value>
36 Map &operator()(Map &map, Key const &key, Value const &value) const
37 {
38 map.insert(typename Map::value_type(key, value));
39 return map;
40 }
41};
42
43// Work-arounds for Microsoft Visual C++ 7.1
44#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
45#define MapListOf(x) proto::call<MapListOf(x)>
46#define _value(x) call<proto::_value(x)>
47#endif
48
49// The grammar for valid map-list expressions, and a
50// transform that populates the map.
51struct MapListOf
52 : proto::or_<
53 proto::when<
54 // map_list_of(a,b)
55 proto::function<
56 proto::terminal<map_list_of_tag>
57 , proto::terminal<_>
58 , proto::terminal<_>
59 >
60 , insert(
61 proto::_data
62 , proto::_value(proto::_child1)
63 , proto::_value(proto::_child2)
64 )
65 >
66 , proto::when<
67 // map_list_of(a,b)(c,d)...
68 proto::function<
69 MapListOf
70 , proto::terminal<_>
71 , proto::terminal<_>
72 >
73 , insert(
74 MapListOf(proto::_child0)
75 , proto::_value(proto::_child1)
76 , proto::_value(proto::_child2)
77 )
78 >
79 >
80{};
81
82#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
83#undef MapListOf
84#undef _value
85#endif
86
87template<typename Expr>
88struct map_list_of_expr;
89
90struct map_list_of_dom
91 : proto::domain<proto::pod_generator<map_list_of_expr>, MapListOf>
92{};
93
94// An expression wrapper that provides a conversion to a
95// map that uses the MapListOf
96template<typename Expr>
97struct map_list_of_expr
98{
99 BOOST_PROTO_BASIC_EXTENDS(Expr, map_list_of_expr, map_list_of_dom)
100 BOOST_PROTO_EXTENDS_FUNCTION()
101
102 template<typename Key, typename Value, typename Cmp, typename Al>
103 operator std::map<Key, Value, Cmp, Al> () const
104 {
105 BOOST_MPL_ASSERT((proto::matches<Expr, MapListOf>));
106 std::map<Key, Value, Cmp, Al> map;
107 return MapListOf()(*this, 0, map);
108 }
109};
110
111map_list_of_expr<proto::terminal<map_list_of_tag>::type> const map_list_of = {.proto_expr_: {.child0: {}}};
112
113int main()
114{
115 // Initialize a map:
116 std::map<std::string, int> op =
117 map_list_of
118 ("<", 1)
119 ("<=",2)
120 (">", 3)
121 (">=",4)
122 ("=", 5)
123 ("<>",6)
124 ;
125
126 std::cout << "\"<\" --> " << op["<"] << std::endl;
127 std::cout << "\"<=\" --> " << op["<="] << std::endl;
128 std::cout << "\">\" --> " << op[">"] << std::endl;
129 std::cout << "\">=\" --> " << op[">="] << std::endl;
130 std::cout << "\"=\" --> " << op["="] << std::endl;
131 std::cout << "\"<>\" --> " << op["<>"] << std::endl;
132
133 return 0;
134}
135//]
136
137

source code of boost/libs/proto/example/map_assign.cpp