summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/proto/example/map_assign.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/proto/example/map_assign.cpp')
-rw-r--r--src/boost/libs/proto/example/map_assign.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/boost/libs/proto/example/map_assign.cpp b/src/boost/libs/proto/example/map_assign.cpp
new file mode 100644
index 000000000..939110594
--- /dev/null
+++ b/src/boost/libs/proto/example/map_assign.cpp
@@ -0,0 +1,136 @@
+//[ MapAssign
+// Copyright 2008 Eric Niebler. 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)
+//
+// This is a port of map_list_of() from the Boost.Assign library.
+// It has the advantage of being more efficient at runtime by not
+// building any temporary container that requires dynamic allocation.
+
+#include <map>
+#include <string>
+#include <iostream>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
+#include <boost/type_traits/add_reference.hpp>
+namespace proto = boost::proto;
+using proto::_;
+
+struct map_list_of_tag
+{};
+
+// A simple callable function object that inserts a
+// (key,value) pair into a map.
+struct insert
+ : proto::callable
+{
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Map, typename Key, typename Value>
+ struct result<This(Map, Key, Value)>
+ : boost::add_reference<Map>
+ {};
+
+ template<typename Map, typename Key, typename Value>
+ Map &operator()(Map &map, Key const &key, Value const &value) const
+ {
+ map.insert(typename Map::value_type(key, value));
+ return map;
+ }
+};
+
+// Work-arounds for Microsoft Visual C++ 7.1
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#define MapListOf(x) proto::call<MapListOf(x)>
+#define _value(x) call<proto::_value(x)>
+#endif
+
+// The grammar for valid map-list expressions, and a
+// transform that populates the map.
+struct MapListOf
+ : proto::or_<
+ proto::when<
+ // map_list_of(a,b)
+ proto::function<
+ proto::terminal<map_list_of_tag>
+ , proto::terminal<_>
+ , proto::terminal<_>
+ >
+ , insert(
+ proto::_data
+ , proto::_value(proto::_child1)
+ , proto::_value(proto::_child2)
+ )
+ >
+ , proto::when<
+ // map_list_of(a,b)(c,d)...
+ proto::function<
+ MapListOf
+ , proto::terminal<_>
+ , proto::terminal<_>
+ >
+ , insert(
+ MapListOf(proto::_child0)
+ , proto::_value(proto::_child1)
+ , proto::_value(proto::_child2)
+ )
+ >
+ >
+{};
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#undef MapListOf
+#undef _value
+#endif
+
+template<typename Expr>
+struct map_list_of_expr;
+
+struct map_list_of_dom
+ : proto::domain<proto::pod_generator<map_list_of_expr>, MapListOf>
+{};
+
+// An expression wrapper that provides a conversion to a
+// map that uses the MapListOf
+template<typename Expr>
+struct map_list_of_expr
+{
+ BOOST_PROTO_BASIC_EXTENDS(Expr, map_list_of_expr, map_list_of_dom)
+ BOOST_PROTO_EXTENDS_FUNCTION()
+
+ template<typename Key, typename Value, typename Cmp, typename Al>
+ operator std::map<Key, Value, Cmp, Al> () const
+ {
+ BOOST_MPL_ASSERT((proto::matches<Expr, MapListOf>));
+ std::map<Key, Value, Cmp, Al> map;
+ return MapListOf()(*this, 0, map);
+ }
+};
+
+map_list_of_expr<proto::terminal<map_list_of_tag>::type> const map_list_of = {{{}}};
+
+int main()
+{
+ // Initialize a map:
+ std::map<std::string, int> op =
+ map_list_of
+ ("<", 1)
+ ("<=",2)
+ (">", 3)
+ (">=",4)
+ ("=", 5)
+ ("<>",6)
+ ;
+
+ 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;
+}
+//]
+