File: map_assign.cpp

package info (click to toggle)
boost1.42 1.42.0-4
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 277,864 kB
  • ctags: 401,076
  • sloc: cpp: 1,235,659; xml: 74,142; ansic: 41,313; python: 26,756; sh: 11,840; cs: 2,118; makefile: 655; perl: 494; yacc: 456; asm: 353; csh: 6
file content (123 lines) | stat: -rw-r--r-- 3,375 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//[ 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;
    }
};

// The grammar for valid map-list expressions, and a
// transform that populates the map.
struct MapListOf
  : proto::or_<
        proto::when<
            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<
            proto::function<
                MapListOf
              , proto::terminal<_>
              , proto::terminal<_>
            >
          , insert(
                MapListOf(proto::_child0)
              , proto::_value(proto::_child1)
              , proto::_value(proto::_child2)
            )
        >
    >
{};

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;
}
//]