26#ifndef DCCLV5FIELDCODECDEFAULT20240101H
27#define DCCLV5FIELDCODECDEFAULT20240101H
29#include "../codecs4/field_codec_default.h"
32#include "../numeric.h"
45template <
typename WireType,
typename FieldType = WireType>
56 dc.regenerate(this->this_message(), this->root_message());
72 dc.regenerate(this->this_message(), this->root_message());
85 virtual double resolution()
88 return std::pow(10.0, -precision());
96 "missing (dccl.field).min");
98 "missing (dccl.field).max");
101 "(dccl.field).resolution must be greater than 0");
105 "at most one of either (dccl.field).precision or (dccl.field).resolution can be set");
107 validate_numeric_bounds();
110 void validate_numeric_bounds()
114 std::numeric_limits<WireType>::lowest(),
115 "(dccl.field).min must be >= minimum of this field type.");
117 std::numeric_limits<WireType>::max(),
118 "(dccl.field).max must be <= maximum of this field type.");
121 const double min_max_eps = 1e-10;
122 bool min_multiple_of_res = std::abs(
quantize(min(), resolution()) - min()) < min_max_eps;
123 bool max_multiple_of_res = std::abs(
quantize(max(), resolution()) - max()) < min_max_eps;
129 "(dccl.field).min must be an exact multiple of (dccl.field).resolution");
132 "(dccl.field).max must be an exact multiple of (dccl.field).resolution");
136 auto res = resolution();
138 if (!min_multiple_of_res)
139 dccl::dlog.is(dccl::logger::WARN, dccl::logger::GENERAL) &&
140 dccl::dlog <<
"Warning: (dccl.field).min should be an exact multiple of "
141 "10^(-(dccl.field).precision), i.e. "
142 << res <<
": " << this->
this_field()->DebugString() << std::endl;
143 if (!max_multiple_of_res)
144 dccl::dlog.is(dccl::logger::WARN, dccl::logger::GENERAL) &&
145 dccl::dlog <<
"Warning: (dccl.field).max should be an exact multiple of "
146 "10^(-(dccl.field).precision), i.e. "
147 << res <<
": " << this->
this_field()->DebugString() << std::endl;
152 std::numeric_limits<double>::digits,
153 "[(dccl.field).max-(dccl.field).min]/(dccl.field).resolution must "
154 "fit in a double-precision floating point value. Please increase "
155 "min, decrease max, or decrease precision.");
162 dccl::dlog.is(dccl::logger::DEBUG2, dccl::logger::ENCODE) &&
163 dlog <<
"Encode " << value <<
" with bounds: [" << min() <<
"," << max() <<
"]"
166 double res = resolution();
167 double tol = res / 2;
169 if (!(min() - tol <= value && value < max() + tol))
174 std::string(
"Value exceeds min/max bounds for field: ") +
182 dccl::uint64 uint_value = dccl::encode(value, min(), res);
195 dccl::dlog.is(dccl::logger::DEBUG2, dccl::logger::DECODE) &&
196 dlog <<
"Decode with bounds: [" << min() <<
"," << max() <<
"]" << std::endl;
202 dccl::uint64 uint_value = (bits->template to<dccl::uint64>)();
211 return dccl::decode<WireType>(uint_value, min(), resolution());
222 return dccl::ceil_log2((max() - min()) / resolution() + 1 + NULL_VALUE);
227using DefaultBoolCodec = v4::DefaultBoolCodec;
228using DefaultEnumCodec = v4::DefaultEnumCodec;
230using DefaultBytesCodec = v4::DefaultBytesCodec;
231using DefaultStringCodec = v4::DefaultStringCodec;
233template <
typename TimeType>
using TimeCodec = v4::TimeCodec<TimeType>;
234template <
typename T>
using StaticCodec = v4::StaticCodec<T>;
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy....
void from(IntType value, size_type num_bits=std::numeric_limits< IntType >::digits)
Sets value of the Bitset to the contents of an integer.
const google::protobuf::Descriptor * this_descriptor() const
Returns the Descriptor (message schema meta-data) for the immediate parent Message.
const google::protobuf::FieldDescriptor * this_field() const
Returns the FieldDescriptor (field schema meta-data) for this field.
void require(bool b, const std::string &description)
Essentially an assertion to be used in the validate() virtual method.
dccl::DCCLFieldOptions dccl_field_options() const
Get the DCCL field option extension value for the current field.
bool use_required()
Whether to use the required or optional encoding.
Exception used to signal null (non-existent) value within field codecs during decode.
Base class for static-typed field encoders/decoders that use a fixed number of bits on the wire regar...
Provides a basic bounded arbitrary length numeric (double, float, uint32, uint64, int32,...
WireType decode(Bitset *bits) override
Decode a field. If the field is empty (i.e. was encoded using the zero-argument encode()),...
Bitset encode() override
Encode an empty field.
void validate() override
Validate a field. Use require() inside your overloaded validate() to assert requirements or throw Exc...
unsigned size() override
The size of the encoded message in bits. Use TypedFieldCodec if the size depends on the data.
DCCL version 5 default field codecs.
Dynamic Compact Control Language namespace.
std::enable_if< std::is_floating_point< Float >::value, Float >::type quantize(Float value, double interval)
google::protobuf::uint64 uint64
an unsigned 64 bit integer
unsigned ceil_log2(dccl::uint64 v)