-
Notifications
You must be signed in to change notification settings - Fork 0
/
Element.cpp
191 lines (166 loc) · 5.05 KB
/
Element.cpp
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/**
* @file Element.cpp
* @author Dan R. Lipsa
*
* Definitions for methods of the Element class.
*/
#include "Attribute.h"
#include "AttributeCreator.h"
#include "AttributeInfo.h"
#include "Debug.h"
#include "Element.h"
#include "Utils.h"
#include "NameSemanticValue.h"
// Private Classes
// ======================================================================
/**
* Functor that stores an attribute in an element.
*/
class storeAttribute :
public unary_function < NameSemanticValue*, void>
{
public:
/**
* Constructor for the functor
* @param where element where to store the attribute
* @param infos information about attributes and how are they created
*/
storeAttribute(
Element& where, const AttributesInfo& infos) :
m_where (where), m_infos (infos) {}
/**
* Stores an attribute
* @param nameSemanticValue Name and value of the attribute
*/
void operator() (const NameSemanticValue* nv)
{
operator () (*nv);
}
void operator() (const NameSemanticValue& nv)
{
try
{
boost::shared_ptr<AttributeInfo> info =
m_infos.GetAttributeInfo (nv.GetName ());
size_t index = info->GetIndex ();
if (index == INVALID_INDEX)
return;
else
{
AttributeCreator& creator = info->GetCreator ();
m_where.SetAttribute (
index, creator(nv.GetSemanticValue (), nv.GetType ()));
}
}
catch (exception& e)
{
throw logic_error (string(nv.GetName ()) + ": "
+ e.what ());
}
}
private:
/**
* Element where the attribute is stored
*/
Element& m_where;
/**
* Information about all attributes and how they are created.
*/
const AttributesInfo& m_infos;
};
// Methods
// ======================================================================
Element::Element(size_t id, ElementStatus::Enum duplicateStatus) :
m_id (id),
m_duplicateStatus (duplicateStatus)
{
}
Element::Element (const Element& other) :
m_id (other.m_id),
m_duplicateStatus (other.m_duplicateStatus)
{
m_attributes.resize (other.m_attributes.size ());
m_attributes = other.m_attributes;
}
void Element::SetAttribute (size_t i, Attribute* attribute)
{
resizeAllowIndex (&m_attributes, i);
boost::shared_ptr<Attribute> p(attribute);
m_attributes[i] = p;
}
void Element::storeAttribute (
const NameSemanticValue& nv, const AttributesInfo& infos)
{
::storeAttribute (*this, infos) (nv);
}
void Element::StoreAttribute (
const char* name, double r, const AttributesInfo& infos)
{
NameSemanticValue nv (name, r);
storeAttribute (nv, infos);
}
void Element::StoreAttributes (
vector<NameSemanticValue*>& list, const AttributesInfo& infos)
{
for_each (list.begin (), list.end (), ::storeAttribute(*this, infos));
}
ostream& Element::PrintAttributes (ostream& ostr,
const AttributesInfo* infos) const
{
if (HasAttributes ())
for (size_t i = 0; i < m_attributes.size (); ++i)
if (HasAttribute (i))
{
if (infos != 0)
ostr << infos->GetAttributeName (i) << ": ";
ostr << m_attributes[i] << " ";
}
return ostr;
}
string Element::GetStringId () const
{
ostringstream ostr;
ostr << setw(4) << GetId ();
return ostr.str ();
}
template<typename T, typename TValue>
TValue Element::GetAttribute (size_t i) const
{
RuntimeAssert (HasAttribute (i),
"Attribute does not exist at index ", i,
" for element ", GetId ());
return *boost::static_pointer_cast<T> (m_attributes[i]);
}
template<typename T, typename TValue>
void Element::SetAttribute (size_t i, TValue value)
{
resizeAllowIndex (&m_attributes, i);
boost::shared_ptr<T> attribute =
boost::static_pointer_cast<T> (m_attributes[i]);
if (attribute == 0)
{
attribute = boost::shared_ptr<T> (new T (value));
m_attributes[i] = attribute;
}
else
attribute->set (value);
}
bool Element::HasAttribute (size_t i) const
{
return i < m_attributes.size () && m_attributes[i] != 0;
}
bool Element::HasAttributes () const
{
return ! m_attributes.empty ();
}
// Template instantiations
// ======================================================================
/** @cond */
template void Element::SetAttribute<RealAttribute, double>(unsigned long, double);
template void Element::SetAttribute<ColorAttribute, Color::Enum>(unsigned long, Color::Enum);
template void Element::SetAttribute<IntegerArrayAttribute, std::vector<int, std::allocator<int> > const> (unsigned long, std::vector<int, std::allocator<int> > const);
template double Element::GetAttribute<RealAttribute, double>(unsigned long) const;
template Color::Enum Element::GetAttribute<ColorAttribute, Color::Enum>(unsigned long) const;
template int Element::GetAttribute<IntegerAttribute, int>(unsigned long) const;
template std::vector<int, std::allocator<int> > const Element::GetAttribute<IntegerArrayAttribute, std::vector<int, std::allocator<int> > const>(unsigned long) const;
/** @endcond */