38
38
39
39
namespace cloe {
40
40
41
+ /* *
42
+ * This error is thrown when an unknown component is accessed at a Vehicle.
43
+ */
44
+ class UnknownComponent : public Error {
45
+ public:
46
+ UnknownComponent (const std::string& vehicle,
47
+ const std::string& key,
48
+ const std::vector<std::string>& available_components);
49
+
50
+ const std::string& vehicle () const { return vehicle_; }
51
+ const std::string& unknown_component () const { return unknown_; }
52
+ const std::vector<std::string>& available_components () const ;
53
+
54
+ private:
55
+ std::string vehicle_;
56
+ std::string unknown_;
57
+ std::vector<std::string> available_;
58
+ };
59
+
60
+ /* *
61
+ * This error is thrown when a component is cast to an incorrect type.
62
+ */
63
+ class BadComponentCast : public Error {
64
+ public:
65
+ BadComponentCast (const std::string& vehicle, const std::string& key);
66
+
67
+ const std::string& vehicle () const { return vehicle_; }
68
+ const std::string& component_name () const { return component_; }
69
+
70
+ private:
71
+ std::string vehicle_;
72
+ std::string component_;
73
+ };
74
+
75
+ /* *
76
+ * This error is thrown when a component cannot be added.
77
+ */
78
+ class CannotAddComponent : public Error {
79
+ public:
80
+ CannotAddComponent (const std::string& msg, const std::string& vehicle, const std::string& key);
81
+
82
+ const std::string& vehicle () const { return vehicle_; }
83
+ const std::string& component_name () const { return component_; }
84
+
85
+ private:
86
+ std::string vehicle_;
87
+ std::string component_;
88
+ };
89
+
41
90
/* *
42
91
* A Vehicle is a collection of sensor and actuator components.
43
92
*
@@ -91,36 +140,40 @@ class Vehicle : public Model {
91
140
}
92
141
93
142
/* *
94
- * Return the component with the given key if it exists .
143
+ * Return the component associated with the key.
95
144
*
96
- * This may throw std::out_of_range.
145
+ * This may throw one of:
146
+ * - UnknownComponent
147
+ * - BadComponentCast
97
148
*/
149
+ template <typename T>
150
+ std::shared_ptr<const T> get (const std::string& key) const {
151
+ auto ptr = std::dynamic_pointer_cast<const T>(at (key));
152
+ if (ptr == nullptr ) {
153
+ throw BadComponentCast (name (), key);
154
+ }
155
+ return ptr;
156
+ }
157
+
98
158
template <typename T>
99
159
std::shared_ptr<T> get (const std::string& key) {
100
- return std::dynamic_pointer_cast <T>(at (key));
160
+ return std::const_pointer_cast <T>(const_cast < const Vehicle&>(* this ). get <T> (key));
101
161
}
102
162
103
163
/* *
104
- * Return the component associated with the standard Cloe enum value.
164
+ * Return the component associated with the enum value.
105
165
*
106
166
* Under-the-hood, the enum is translated to a string, which is used to fetch
107
167
* the correct component.
108
- *
109
- * This may throw std::out_of_range.
110
168
*/
111
169
template <typename T, typename Enum, std::enable_if_t <std::is_enum<Enum>::value, int > = 0 >
112
- std::shared_ptr<T> get (Enum c) {
113
- return std::dynamic_pointer_cast<T>(at (to_string (c)));
114
- }
115
-
116
- template <typename T>
117
- std::shared_ptr<const T> get (const std::string& key) const {
118
- return std::dynamic_pointer_cast<const T>(at (key));
170
+ std::shared_ptr<const T> get (Enum c) const {
171
+ return get<T>(to_string (c));
119
172
}
120
173
121
174
template <typename T, typename Enum, std::enable_if_t <std::is_enum<Enum>::value, int > = 0 >
122
- std::shared_ptr<const T> get (Enum c) const {
123
- return std::dynamic_pointer_cast <T>(at ( to_string (c) ));
175
+ std::shared_ptr<T> get (Enum c) {
176
+ return get <T>(to_string (c));
124
177
}
125
178
126
179
public: // Component Management
@@ -144,8 +197,7 @@ class Vehicle : public Model {
144
197
145
198
void add_component (std::shared_ptr<Component> sp, const std::string& alias) {
146
199
if (this ->has (alias)) {
147
- // TODO(ben): Add better error type here with explanation
148
- throw std::runtime_error (" component already exists in the vehicle" );
200
+ throw CannotAddComponent (" component already exists" , name (), alias);
149
201
}
150
202
this ->set_component (alias, sp);
151
203
}
@@ -230,25 +282,6 @@ class Vehicle : public Model {
230
282
std::map<std::string, std::shared_ptr<Component>> components_;
231
283
};
232
284
233
- /* *
234
- * This error is thrown when an unknown component is accessed at a Vehicle.
235
- */
236
- class UnknownComponentError : public Error {
237
- public:
238
- UnknownComponentError (const std::string& vehicle,
239
- const std::string& key,
240
- const std::vector<std::string>& available_components);
241
-
242
- const std::string& vehicle () const { return vehicle_; }
243
- const std::string& unknown_component () const { return unknown_; }
244
- const std::vector<std::string>& available_components () const ;
245
-
246
- private:
247
- std::string vehicle_;
248
- std::string unknown_;
249
- std::vector<std::string> available_;
250
- };
251
-
252
285
} // namespace cloe
253
286
254
287
#endif // CLOE_VEHICLE_HPP_
0 commit comments