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);
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.
bool is(logger::Verbosity verbosity, logger::Group group=logger::GENERAL)
Indicates the verbosity of the Logger until the next std::flush or std::endl. The boolean return is u...
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 bool encoder. Uses 1 bit if field is required, 2 bits if optional
Placeholder codec that takes no space on the wire (0 bits).
Provides an enum encoder. This converts the enumeration to an integer and uses DefaultNumericFieldCod...
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(const WireType &value) override
Encode a non-empty field.
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.
Dynamic Compact Control Language namespace.
google::protobuf::uint64 uint64
an unsigned 64 bit integer
std::enable_if< std::is_floating_point< Float >::value, Float >::type quantize(Float value, double interval)
unsigned ceil_log2(dccl::uint64 v)