@@ -11,7 +11,7 @@ namespace BT
1111{
1212
1313/* *
14- * To add new type to the JSON library, you should follow these isntructions :
14+ * To add new type to the JSON library, you should follow these instructions :
1515* https://json.nlohmann.me/features/arbitrary_types/
1616*
1717* Considering for instance the type:
@@ -80,22 +80,31 @@ class JsonExporter
8080 template <typename T>
8181 Expected<T> fromJson (const nlohmann::json& source) const ;
8282
83- // / Register new JSON converters with addConverter<Foo>().
84- // / You should have used first the macro BT_JSON_CONVERTER
83+ /* *
84+ * @brief Register new JSON converters with addConverter<Foo>().
85+ * You should used first the macro BT_JSON_CONVERTER.
86+ * The convertions from/to vector<T> are automatically registered.
87+ */
8588 template <typename T>
8689 void addConverter ();
8790
8891 /* *
8992 * @brief addConverter register a to_json function that converts a json to a type T.
93+ * The convertion to std:vector<T> is automatically registered.
9094 *
9195 * @param to_json the function with signature void(const T&, nlohmann::json&)
9296 * @param add_type if true, add a field called [__type] with the name ofthe type.
93- * * /
97+ */
9498 template <typename T>
9599 void addConverter (std::function<void (const T&, nlohmann::json&)> to_json,
96100 bool add_type = true);
97101
98- // / Register custom from_json converter directly.
102+ /* *
103+ * @brief addConverter register a from_json function that converts a json to a type T.
104+ * The convertions from std::vector<T> is automatically registered.
105+ *
106+ * @param from_json the function with signature void(const nlohmann::json&, T&)
107+ */
99108 template <typename T>
100109 void addConverter (std::function<void (const nlohmann::json&, T&)> from_json);
101110
@@ -105,6 +114,7 @@ class JsonExporter
105114
106115 std::unordered_map<std::type_index, ToJonConverter> to_json_converters_;
107116 std::unordered_map<std::type_index, FromJonConverter> from_json_converters_;
117+ std::unordered_map<std::type_index, FromJonConverter> from_json_array_converters_;
108118 std::unordered_map<std::string, BT::TypeInfo> type_names_;
109119};
110120
@@ -129,6 +139,15 @@ inline Expected<T> JsonExporter::fromJson(const nlohmann::json& source) const
129139template <typename T>
130140inline void JsonExporter::addConverter ()
131141{
142+ // we need to get the name of the type
143+ nlohmann::json const js = T{};
144+ // we insert both the name obtained from JSON and demangle
145+ if (js.contains (" __type" ))
146+ {
147+ type_names_.insert ({ std::string (js[" __type" ]), BT::TypeInfo::Create<T>() });
148+ }
149+ type_names_.insert ({ BT::demangle (typeid (T)), BT::TypeInfo::Create<T>() });
150+
132151 ToJonConverter to_converter = [](const BT::Any& entry, nlohmann::json& dst) {
133152 dst = *const_cast <BT::Any&>(entry).castPtr <T>();
134153 };
@@ -139,16 +158,23 @@ inline void JsonExporter::addConverter()
139158 return { BT::Any (value), BT::TypeInfo::Create<T>() };
140159 };
141160
142- // we need to get the name of the type
143- nlohmann::json const js = T{};
144- // we insert both the name obtained from JSON and demangle
145- if (js.contains (" __type" ))
146- {
147- type_names_.insert ({ std::string (js[" __type" ]), BT::TypeInfo::Create<T>() });
148- }
149- type_names_.insert ({ BT::demangle (typeid (T)), BT::TypeInfo::Create<T>() });
150-
151161 from_json_converters_.insert ({ typeid (T), from_converter });
162+
163+ // ---- include vectors of T
164+ ToJonConverter to_array_converter = [](const BT::Any& entry, nlohmann::json& dst) {
165+ dst = *const_cast <BT::Any&>(entry).castPtr <std::vector<T>>();
166+ };
167+ to_json_converters_.insert ({ typeid (std::vector<T>), to_array_converter });
168+
169+ FromJonConverter from_array_converter = [](const nlohmann::json& src) -> Entry {
170+ std::vector<T> value;
171+ for (const auto & item : src)
172+ {
173+ value.push_back (item.get <T>());
174+ }
175+ return { BT::Any (value), BT::TypeInfo::Create<std::vector<T>>() };
176+ };
177+ from_json_array_converters_.insert ({ typeid (T), from_array_converter });
152178}
153179
154180template <typename T>
@@ -163,6 +189,18 @@ inline void JsonExporter::addConverter(
163189 }
164190 };
165191 to_json_converters_.insert ({ typeid (T), std::move (converter) });
192+ // ---------------------------------------------
193+ // add the vector<T> converter
194+ auto vector_converter = [converter](const BT::Any& entry, nlohmann::json& json) {
195+ auto & vec = *const_cast <BT::Any&>(entry).castPtr <std::vector<T>>();
196+ for (const auto & item : vec)
197+ {
198+ nlohmann::json item_json;
199+ converter (BT::Any (item), item_json);
200+ json.push_back (item_json);
201+ }
202+ };
203+ to_json_converters_.insert ({ typeid (std::vector<T>), std::move (vector_converter) });
166204}
167205
168206template <typename T>
@@ -176,6 +214,19 @@ JsonExporter::addConverter(std::function<void(const nlohmann::json&, T&)> func)
176214 };
177215 type_names_.insert ({ BT::demangle (typeid (T)), BT::TypeInfo::Create<T>() });
178216 from_json_converters_.insert ({ typeid (T), std::move (converter) });
217+ // ---------------------------------------------
218+ // add the vector<T> converter
219+ auto vector_converter = [func](const nlohmann::json& json) -> Entry {
220+ std::vector<T> tmp;
221+ for (const auto & item : json)
222+ {
223+ T item_tmp;
224+ func (item, item_tmp);
225+ tmp.push_back (item_tmp);
226+ }
227+ return { BT::Any (tmp), BT::TypeInfo::Create<std::vector<T>>() };
228+ };
229+ from_json_array_converters_.insert ({ typeid (T), std::move (vector_converter) });
179230}
180231
181232template <typename T>
0 commit comments