55 http://www.boost.org/LICENSE_1_0.txt)
66------------------------------------------------------------------------------*/
77
8+ #include < sstream>
89#include < utility>
910#include " ../error.hpp"
1011#include " ../variant.hpp"
@@ -119,16 +120,40 @@ FromVariantConverter& FromVariantConverter::operator()(T& value)
119120 @pre The variant is an array.
120121 @pre There are elements left in the variant array.
121122 @pre The element is convertible to the destination type.
122- @throws error::Access if the variant is not an array.
123- @throws std::out_of_range if there are no elements left in the
123+ @throws error::Conversion if the variant is not an array.
124+ @throws error::Conversion if there are no elements left in the
124125 variant array.
125126 @throws error::Conversion if the element is not convertible to the
126127 destination type. */
127128template <typename T>
128129FromVariantConverter& FromVariantConverter::operator [](T& value)
129130{
130- var_.as <Array>().at (index_).to (value);
131- ++index_;
131+ try
132+ {
133+ var_.at (index_).to (value);
134+ ++index_;
135+ }
136+ catch (const error::Conversion& e)
137+ {
138+ std::ostringstream oss;
139+ oss << e.what () << " , for array index " << index_;
140+ throw error::Conversion (oss.str ());
141+ }
142+ catch (const error::Access&)
143+ {
144+ std::ostringstream oss;
145+ oss << " wamp::error::Conversion: Attemping to access field type "
146+ << typeNameOf (var_) << " as array" ;
147+ throw error::Conversion (oss.str ());
148+ }
149+ catch (const std::out_of_range&)
150+ {
151+ std::ostringstream oss;
152+ oss << " wamp::error::Conversion: Cannot extract more than " << index_
153+ << " elements from the array" ;
154+ throw error::Conversion (oss.str ());
155+ }
156+
132157 return *this ;
133158}
134159
@@ -137,29 +162,77 @@ FromVariantConverter& FromVariantConverter::operator[](T& value)
137162 @pre The variant is an object.
138163 @pre There exists a member with the given key.
139164 @pre The member is convertible to the destination type.
140- @throws error::Access if the variant is not an object.
141- @throws std::out_of_range if there doesn't exist a member with the
165+ @throws error::Conversion if the variant is not an object.
166+ @throws error::Conversion if there doesn't exist a member with the
142167 given key.
143168 @throws error::Conversion if the member is not convertible to the
144169 destination type. */
145170template <typename T>
146171FromVariantConverter& FromVariantConverter::operator ()(const String& key,
147172 T& value)
148173{
149- var_.as <Object>().at (key).to (value);
174+ try
175+ {
176+ var_.at (key).to (value);
177+ }
178+ catch (const error::Conversion& e)
179+ {
180+ std::ostringstream oss;
181+ oss << e.what () << " , for object member \" " << key << ' "' ;
182+ throw error::Conversion (oss.str ());
183+ }
184+ catch (const error::Access&)
185+ {
186+ std::ostringstream oss;
187+ oss << " wamp::error::Conversion: Attemping to access field type "
188+ << typeNameOf (var_) << " as object using key \" " << key << ' "' ;
189+ throw error::Conversion (oss.str ());
190+ }
191+ catch (const std::out_of_range&)
192+ {
193+ std::ostringstream oss;
194+ oss << " wamp::error::Conversion: Key \" " << key
195+ << " \" not found in object" ;
196+ throw error::Conversion (oss.str ());
197+ }
198+
150199 return *this ;
151200}
152201
202+ /* * @details
203+ The member is converted to the destination type via Variant::to.
204+ @pre The variant is an object.
205+ @pre The member, if it exists, is convertible to the destination type.
206+ @throws error::Conversion if the variant is not an object.
207+ @throws error::Conversion if the existing member is not convertible to the
208+ destination type. */
153209template <typename T, typename U>
154210FromVariantConverter& FromVariantConverter::operator ()(const String& key,
155211 T& value, U&& fallback)
156212{
157- auto & obj = var_.as <Object>();
158- auto kv = obj.find (key);
159- if (kv != obj.end ())
160- kv->second .to (value);
161- else
162- value = std::forward<U>(fallback);
213+ try
214+ {
215+ auto & obj = var_.as <Object>();
216+ auto kv = obj.find (key);
217+ if (kv != obj.end ())
218+ kv->second .to (value);
219+ else
220+ value = std::forward<U>(fallback);
221+ }
222+ catch (const error::Conversion& e)
223+ {
224+ std::ostringstream oss;
225+ oss << e.what () << " , for object member \" " << key << ' "' ;
226+ throw error::Conversion (oss.str ());
227+ }
228+ catch (const error::Access&)
229+ {
230+ std::ostringstream oss;
231+ oss << " wamp::error::Conversion: Attemping to access field type "
232+ << typeNameOf (var_) << " as object using key \" " << key << ' "' ;
233+ throw error::Conversion (oss.str ());
234+ }
235+
163236 return *this ;
164237}
165238
@@ -181,7 +254,7 @@ template <typename TObject>
181254void ConversionAccess::convertFrom (FromVariantConverter& c, TObject& obj)
182255{
183256 static_assert (has_member_convertFrom<TObject>(),
184- " The 'convertFrom' member function has not provided "
257+ " The 'convertFrom' member function has not been provided "
185258 " for this type." );
186259 obj.convertFrom (c);
187260}
@@ -190,11 +263,13 @@ template <typename TObject>
190263void ConversionAccess::convertTo (ToVariantConverter& c, const TObject& obj)
191264{
192265 static_assert (has_member_convertTo<TObject>(),
193- " The 'convertTo' member function has not provided "
194- " for this type." );
266+ " The 'convertTo' member function has not been provided for this type." );
195267 obj.convertTo (c);
196268}
197269
270+ template <typename TObject>
271+ TObject ConversionAccess::defaultConstruct () {return TObject ();}
272+
198273
199274// ------------------------------------------------------------------------------
200275template <typename TConverter, typename TValue>
0 commit comments