26 #ifndef DCCLFIELDCODECTYPED20120312H
27 #define DCCLFIELDCODECTYPED20120312H
29 #include <type_traits>
31 #include "field_codec.h"
37 template <
typename WireType,
typename FieldType,
class Enable =
void>
45 virtual WireType
pre_encode(
const FieldType& field_value) = 0;
51 virtual FieldType
post_decode(
const WireType& wire_value) = 0;
55 template <
typename WireType,
typename FieldType>
57 std::enable_if_t<std::is_same<WireType, FieldType>::value>>
62 virtual WireType
pre_encode(
const FieldType& field_value) {
return field_value; }
64 virtual FieldType
post_decode(
const WireType& wire_value) {
return wire_value; }
72 template <
typename WireType,
typename FieldType = WireType>
76 using wire_type = WireType;
77 using field_type = FieldType;
100 virtual unsigned size() = 0;
106 virtual unsigned size(
const WireType& wire_value) = 0;
109 unsigned any_size(
const dccl::any& wire_value)
override
113 return is_empty(wire_value) ?
size() :
size(dccl::any_cast<WireType>(wire_value));
115 catch (dccl::bad_any_cast&)
117 throw(type_error(
"size",
typeid(WireType), wire_value.type()));
121 void any_encode(
Bitset* bits,
const dccl::any& wire_value)
override
125 *bits = is_empty(wire_value) ?
encode() :
encode(dccl::any_cast<WireType>(wire_value));
127 catch (dccl::bad_any_cast&)
129 throw(type_error(
"encode",
typeid(WireType), wire_value.type()));
133 void any_decode(
Bitset* bits, dccl::any* wire_value)
override
135 any_decode_specific<WireType>(bits, wire_value);
138 void any_pre_encode(dccl::any* wire_value,
const dccl::any& field_value)
override
142 if (!is_empty(field_value))
143 *wire_value = this->
pre_encode(dccl::any_cast<FieldType>(field_value));
145 catch (dccl::bad_any_cast&)
147 throw(type_error(
"pre_encode",
typeid(FieldType), field_value.type()));
151 *wire_value = dccl::any();
155 void any_post_decode(
const dccl::any& wire_value, dccl::any* field_value)
override
157 any_post_decode_specific<WireType>(wire_value, field_value);
161 template <
typename T>
162 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
163 any_post_decode_specific(
const dccl::any& wire_value, dccl::any* field_value)
165 *field_value = wire_value;
168 template <
typename T>
169 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
170 any_post_decode_specific(
const dccl::any& wire_value, dccl::any* field_value)
174 if (!is_empty(wire_value))
175 *field_value = this->
post_decode(dccl::any_cast<WireType>(wire_value));
177 catch (dccl::bad_any_cast&)
179 throw(type_error(
"post_decode",
typeid(WireType), wire_value.type()));
183 *field_value = dccl::any();
187 template <
typename T>
188 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
189 any_decode_specific(
Bitset* bits, dccl::any* wire_value)
193 auto* msg = dccl::any_cast<google::protobuf::Message*>(*wire_value);
194 msg->CopyFrom(
decode(bits));
199 *wire_value = dccl::any();
203 template <
typename T>
204 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
205 any_decode_specific(
Bitset* bits, dccl::any* wire_value)
209 *wire_value =
decode(bits);
213 *wire_value = dccl::any();
223 template <
typename WireType,
typename FieldType = WireType>
227 using wire_type = WireType;
228 using field_type = FieldType;
238 virtual unsigned size_repeated(
const std::vector<WireType>& wire_values) = 0;
267 if (is_empty(return_vec))
270 return return_vec.at(0);
282 unsigned size(
const WireType& wire_value)
override
292 void any_encode_repeated(
Bitset* bits,
const std::vector<dccl::any>& wire_values)
override
296 std::vector<WireType> in;
297 for (
const auto& wire_value : wire_values)
298 { in.push_back(dccl::any_cast<WireType>(wire_value)); } *bits =
encode_repeated(in);
300 catch (dccl::bad_any_cast&)
302 throw(type_error(
"encode_repeated",
typeid(WireType), wire_values.at(0).type()));
306 void any_decode_repeated(Bitset* repeated_bits, std::vector<dccl::any>* field_values)
override
308 any_decode_repeated_specific<WireType>(repeated_bits, field_values);
311 template <
typename T>
312 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
313 any_decode_repeated_specific(Bitset* repeated_bits, std::vector<dccl::any>* wire_values)
316 wire_values->resize(decoded_msgs.size(), WireType());
318 for (
int i = 0, n = decoded_msgs.size(); i < n; ++i)
320 auto* msg = dccl::any_cast<google::protobuf::Message*>(wire_values->at(i));
321 msg->CopyFrom(decoded_msgs[i]);
325 template <
typename T>
326 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
327 any_decode_repeated_specific(Bitset* repeated_bits, std::vector<dccl::any>* wire_values)
330 wire_values->resize(decoded.size(), WireType());
332 for (
int i = 0, n = decoded.size(); i < n; ++i) wire_values->at(i) = decoded[i];
335 void any_pre_encode(dccl::any* wire_value,
const dccl::any& field_value)
override
339 if (!is_empty(field_value))
340 *wire_value = this->
pre_encode(dccl::any_cast<FieldType>(field_value));
342 catch (dccl::bad_any_cast&)
344 throw(type_error(
"pre_encode",
typeid(FieldType), field_value.type()));
346 catch (NullValueException&)
348 *wire_value = dccl::any();
352 void any_post_decode(
const dccl::any& wire_value, dccl::any* field_value)
override
356 if (!is_empty(wire_value))
357 *field_value = this->
post_decode(dccl::any_cast<WireType>(wire_value));
359 catch (dccl::bad_any_cast&)
361 throw(type_error(
"post_decode",
typeid(WireType), wire_value.type()));
363 catch (NullValueException&)
365 *field_value = dccl::any();
375 unsigned any_size_repeated(
const std::vector<dccl::any>& wire_values)
override
379 std::vector<WireType> in;
380 for (
const auto& wire_value : wire_values)
381 { in.push_back(dccl::any_cast<WireType>(wire_value)); }
return size_repeated(in);
383 catch (dccl::bad_any_cast&)
385 throw(type_error(
"size_repeated",
typeid(WireType), wire_values.at(0).type()));