blob: 393ad47c1121f797e42581ea13dc653df0d6a12a (
plain)
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
|
// file : build/variable -*- C++ -*-
// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC
// license : MIT; see accompanying LICENSE file
#ifndef BUILD_VARIABLE
#define BUILD_VARIABLE
#include <string>
#include <memory> // unique_ptr
#include <utility> // move()
#include <typeindex>
#include <unordered_set>
#include <build/name>
#include <build/prefix-map>
namespace build
{
class scope;
struct value;
struct value_type
{
std::type_index id;
value* (*const factory) ();
};
// variable
//
// The two variables are considered the same if they have the same name.
//
struct variable
{
explicit
variable (std::string n): name (std::move (n)), type (nullptr) {}
std::string name;
const value_type* type; // If NULL, then this variable has no fixed type.
};
inline bool
operator== (const variable& x, const variable& y) {return x.name == y.name;}
typedef std::reference_wrapper<const variable> variable_cref;
// value
//
struct value
{
typedef build::scope scope_type;
virtual
~value () = default;
value (scope_type& s): scope (s) {}
scope_type& scope; // Scope to which this value belongs.
};
typedef std::unique_ptr<value> value_ptr;
struct list_value: value
{
list_value (scope_type& s, names d): value (s), data (std::move (d)) {}
names data;
};
typedef std::unique_ptr<list_value> list_value_ptr;
}
namespace std
{
template <>
struct hash<build::variable>: hash<string>
{
size_t
operator() (const build::variable& v) const noexcept
{
return hash<string>::operator() (v.name);
}
};
}
namespace build
{
// variable_pool
//
struct variable_set: std::unordered_set<variable>
{
// @@ Need to check/set type?
//
const variable&
find (std::string name) {return *emplace (std::move (name)).first;}
};
extern variable_set variable_pool;
// variable_map
//
template <>
struct compare_prefix<variable_cref>: compare_prefix<std::string>
{
typedef compare_prefix<std::string> base;
explicit
compare_prefix (char d): base (d) {}
bool
operator() (const variable& x, const variable& y) const
{
return base::operator() (x.name, y.name);
}
bool
prefix (const variable& p, const variable& k) const
{
return base::prefix (p.name, k.name);
}
};
typedef prefix_map<variable_cref, value_ptr, '.'> variable_map;
}
#endif // BUILD_VARIABLE
|