25 #ifndef DCCLFIELDCODECTYPED20120312H
26 #define DCCLFIELDCODECTYPED20120312H
28 #include <type_traits>
30 #include "field_codec.h"
36 template <
typename WireType,
typename FieldType,
class Enable =
void>
44 virtual WireType
pre_encode(
const FieldType& field_value) = 0;
50 virtual FieldType
post_decode(
const WireType& wire_value) = 0;
54 template <
typename WireType,
typename FieldType>
56 std::enable_if_t<std::is_same<WireType, FieldType>::value>>
61 virtual WireType
pre_encode(
const FieldType& field_value) {
return field_value; }
63 virtual FieldType
post_decode(
const WireType& wire_value) {
return wire_value; }
71 template <
typename WireType,
typename FieldType = WireType>
75 using wire_type = WireType;
76 using field_type = FieldType;
99 virtual unsigned size() = 0;
105 virtual unsigned size(
const WireType& wire_value) = 0;
108 unsigned any_size(
const dccl::any& wire_value)
override
112 return is_empty(wire_value) ?
size() :
size(dccl::any_cast<WireType>(wire_value));
114 catch (dccl::bad_any_cast&)
116 throw(type_error(
"size",
typeid(WireType), wire_value.type()));
120 void any_encode(
Bitset* bits,
const dccl::any& wire_value)
override
124 *bits = is_empty(wire_value) ?
encode() :
encode(dccl::any_cast<WireType>(wire_value));
126 catch (dccl::bad_any_cast&)
128 throw(type_error(
"encode",
typeid(WireType), wire_value.type()));
132 void any_decode(
Bitset* bits, dccl::any* wire_value)
override
134 any_decode_specific<WireType>(bits, wire_value);
137 void any_pre_encode(dccl::any* wire_value,
const dccl::any& field_value)
override
141 if (!is_empty(field_value))
142 *wire_value = this->
pre_encode(dccl::any_cast<FieldType>(field_value));
144 catch (dccl::bad_any_cast&)
146 throw(type_error(
"pre_encode",
typeid(FieldType), field_value.type()));
150 *wire_value = dccl::any();
154 void any_post_decode(
const dccl::any& wire_value, dccl::any* field_value)
override
156 any_post_decode_specific<WireType>(wire_value, field_value);
160 template <
typename T>
161 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
162 any_post_decode_specific(
const dccl::any& wire_value, dccl::any* field_value)
164 *field_value = wire_value;
167 template <
typename T>
168 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
169 any_post_decode_specific(
const dccl::any& wire_value, dccl::any* field_value)
173 if (!is_empty(wire_value))
174 *field_value = this->
post_decode(dccl::any_cast<WireType>(wire_value));
176 catch (dccl::bad_any_cast&)
178 throw(type_error(
"post_decode",
typeid(WireType), wire_value.type()));
182 *field_value = dccl::any();
186 template <
typename T>
187 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
188 any_decode_specific(
Bitset* bits, dccl::any* wire_value)
192 auto* msg = dccl::any_cast<google::protobuf::Message*>(*wire_value);
193 msg->CopyFrom(
decode(bits));
198 *wire_value = dccl::any();
202 template <
typename T>
203 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
204 any_decode_specific(
Bitset* bits, dccl::any* wire_value)
208 *wire_value =
decode(bits);
212 *wire_value = dccl::any();
222 template <
typename WireType,
typename FieldType = WireType>
226 using wire_type = WireType;
227 using field_type = FieldType;
237 virtual unsigned size_repeated(
const std::vector<WireType>& wire_values) = 0;
266 if (is_empty(return_vec))
269 return return_vec.at(0);
281 unsigned size(
const WireType& wire_value)
override
291 void any_encode_repeated(
Bitset* bits,
const std::vector<dccl::any>& wire_values)
override
295 std::vector<WireType> in;
296 for (
const auto& wire_value : wire_values)
297 { in.push_back(dccl::any_cast<WireType>(wire_value)); } *bits =
encode_repeated(in);
299 catch (dccl::bad_any_cast&)
301 throw(type_error(
"encode_repeated",
typeid(WireType), wire_values.at(0).type()));
305 void any_decode_repeated(Bitset* repeated_bits, std::vector<dccl::any>* field_values)
override
307 any_decode_repeated_specific<WireType>(repeated_bits, field_values);
310 template <
typename T>
311 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
312 any_decode_repeated_specific(Bitset* repeated_bits, std::vector<dccl::any>* wire_values)
315 wire_values->resize(decoded_msgs.size(), WireType());
317 for (
int i = 0, n = decoded_msgs.size(); i < n; ++i)
319 auto* msg = dccl::any_cast<google::protobuf::Message*>(wire_values->at(i));
320 msg->CopyFrom(decoded_msgs[i]);
324 template <
typename T>
325 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
326 any_decode_repeated_specific(Bitset* repeated_bits, std::vector<dccl::any>* wire_values)
329 wire_values->resize(decoded.size(), WireType());
331 for (
int i = 0, n = decoded.size(); i < n; ++i) wire_values->at(i) = decoded[i];
334 void any_pre_encode(dccl::any* wire_value,
const dccl::any& field_value)
override
338 if (!is_empty(field_value))
339 *wire_value = this->
pre_encode(dccl::any_cast<FieldType>(field_value));
341 catch (dccl::bad_any_cast&)
343 throw(type_error(
"pre_encode",
typeid(FieldType), field_value.type()));
345 catch (NullValueException&)
347 *wire_value = dccl::any();
351 void any_post_decode(
const dccl::any& wire_value, dccl::any* field_value)
override
355 if (!is_empty(wire_value))
356 *field_value = this->
post_decode(dccl::any_cast<WireType>(wire_value));
358 catch (dccl::bad_any_cast&)
360 throw(type_error(
"post_decode",
typeid(WireType), wire_value.type()));
362 catch (NullValueException&)
364 *field_value = dccl::any();
374 unsigned any_size_repeated(
const std::vector<dccl::any>& wire_values)
override
378 std::vector<WireType> in;
379 for (
const auto& wire_value : wire_values)
380 { in.push_back(dccl::any_cast<WireType>(wire_value)); }
return size_repeated(in);
382 catch (dccl::bad_any_cast&)
384 throw(type_error(
"size_repeated",
typeid(WireType), wire_values.at(0).type()));