22 #ifndef DCCLFIELDCODECTYPED20120312H
23 #define DCCLFIELDCODECTYPED20120312H
26 #include <boost/type_traits.hpp>
28 #include "field_codec.h"
41 template <
typename WireType,
typename FieldType,
class Enable =
void>
49 virtual WireType
pre_encode(
const FieldType& field_value) = 0;
55 virtual FieldType
post_decode(
const WireType& wire_value) = 0;
60 template <
typename WireType,
typename FieldType>
62 typename boost::enable_if<boost::is_same<WireType, FieldType> >::type>
67 virtual WireType
pre_encode(
const FieldType& field_value)
68 {
return field_value; }
71 {
return wire_value; }
81 template<
typename WireType,
typename FieldType = WireType>
85 typedef WireType wire_type;
86 typedef FieldType field_type;
110 virtual unsigned size() = 0;
116 virtual unsigned size(
const WireType& wire_value) = 0;
119 unsigned any_size(
const boost::any& wire_value)
122 {
return wire_value.empty() ?
size() :
size(boost::any_cast<WireType>(wire_value)); }
123 catch(boost::bad_any_cast&)
124 {
throw(type_error(
"size",
typeid(WireType), wire_value.type())); }
127 void any_encode(
Bitset* bits,
const boost::any& wire_value)
130 { *bits = wire_value.empty() ?
encode() :
encode(boost::any_cast<WireType>(wire_value)); }
131 catch(boost::bad_any_cast&)
132 {
throw(type_error(
"encode",
typeid(WireType), wire_value.type())); }
135 void any_decode(
Bitset* bits, boost::any* wire_value)
137 any_decode_specific<WireType>(bits, wire_value);
142 void any_pre_encode(boost::any* wire_value,
143 const boost::any& field_value)
147 if(!field_value.empty())
148 *wire_value = this->
pre_encode(boost::any_cast<FieldType>(field_value));
150 catch(boost::bad_any_cast&)
152 throw(type_error(
"pre_encode",
typeid(FieldType), field_value.type()));
156 *wire_value = boost::any();
160 void any_post_decode(
const boost::any& wire_value,
161 boost::any* field_value)
163 any_post_decode_specific<WireType>(wire_value, field_value);
169 typename boost::enable_if<boost::is_base_of<google::protobuf::Message, T>,
void>::type
170 any_post_decode_specific(
const boost::any& wire_value, boost::any* field_value,
compiler::dummy<0> dummy = 0)
171 { *field_value = wire_value; }
174 typename boost::disable_if<boost::is_base_of<google::protobuf::Message, T>,
void>::type
175 any_post_decode_specific(
const boost::any& wire_value, boost::any* field_value,
compiler::dummy<1> dummy = 0)
179 if(!wire_value.empty())
180 *field_value = this->
post_decode(boost::any_cast<WireType>(wire_value));
182 catch(boost::bad_any_cast&)
184 throw(type_error(
"post_decode",
typeid(WireType), wire_value.type()));
188 *field_value = boost::any();
194 typename boost::enable_if<boost::is_base_of<google::protobuf::Message, T>,
void>::type
200 msg->CopyFrom(
decode(bits));
205 *wire_value = boost::any();
210 typename boost::disable_if<boost::is_base_of<google::protobuf::Message, T>,
void>::type
214 { *wire_value =
decode(bits); }
216 { *wire_value = boost::any(); }
227 template<
typename WireType,
typename FieldType = WireType>
231 typedef WireType wire_type;
232 typedef FieldType field_type;
243 const std::vector<WireType>& wire_values) = 0;
272 if(return_vec.empty())
275 return return_vec.at(0);
288 virtual unsigned size(
const WireType& wire_value)
289 {
return size_repeated(std::vector<WireType>(1, wire_value)); }
299 void any_encode_repeated(
Bitset* bits,
const std::vector<boost::any>& wire_values)
303 std::vector<WireType> in;
304 for (std::vector<boost::any>::const_iterator it = wire_values.begin(); it != wire_values.end(); ++it)
306 in.push_back(boost::any_cast<WireType>(*it));
311 catch(boost::bad_any_cast&)
312 {
throw(type_error(
"encode_repeated",
typeid(WireType), wire_values.at(0).type())); }
315 void any_decode_repeated(Bitset* repeated_bits, std::vector<boost::any>* field_values)
317 any_decode_repeated_specific<WireType>(repeated_bits, field_values);
321 typename boost::enable_if<boost::is_base_of<google::protobuf::Message, T>,
void>::type
322 any_decode_repeated_specific(Bitset* repeated_bits, std::vector<boost::any>* wire_values, compiler::dummy<0> dummy = 0)
325 wire_values->resize(decoded_msgs.size(), WireType());
327 for(
int i = 0, n = decoded_msgs.size(); i < n; ++i)
330 msg->CopyFrom(decoded_msgs[i]);
335 typename boost::disable_if<boost::is_base_of<google::protobuf::Message, T>,
void>::type
336 any_decode_repeated_specific(Bitset* repeated_bits, std::vector<boost::any>* wire_values, compiler::dummy<1> dummy = 0)
339 wire_values->resize(decoded.size(), WireType());
341 for(
int i = 0, n = decoded.size(); i < n; ++i)
342 wire_values->at(i) = decoded[i];
346 void any_pre_encode(boost::any* wire_value,
347 const boost::any& field_value)
351 if(!field_value.empty())
352 *wire_value = this->
pre_encode(boost::any_cast<FieldType>(field_value));
354 catch(boost::bad_any_cast&)
356 throw(type_error(
"pre_encode",
typeid(FieldType), field_value.type()));
358 catch(NullValueException&)
360 *wire_value = boost::any();
364 void any_post_decode(
const boost::any& wire_value,
365 boost::any* field_value)
369 if(!wire_value.empty())
370 *field_value = this->
post_decode(boost::any_cast<WireType>(wire_value));
372 catch(boost::bad_any_cast&)
374 throw(type_error(
"post_decode",
typeid(WireType), wire_value.type()));
376 catch(NullValueException&)
378 *field_value = boost::any();
388 unsigned any_size_repeated(
const std::vector<boost::any>& wire_values)
392 std::vector<WireType> in;
393 for (std::vector<boost::any>::const_iterator it = wire_values.begin(); it != wire_values.end(); ++it)
395 in.push_back(boost::any_cast<WireType>(*it));
400 catch(boost::bad_any_cast&)
401 {
throw(type_error(
"size_repeated",
typeid(WireType), wire_values.at(0).type())); }