@@ -90,6 +90,9 @@ struct MFAST_CODER_EXPORT fast_encoder_core : mfast::detail::codec_helper {
9090 template <typename T, typename TypeCategory>
9191 void encode_field (const T &ext_ref, constant_operator_tag, TypeCategory);
9292
93+ template <typename T>
94+ void encode_field (const T &ext_ref, copy_operator_tag, number_type_tag);
95+
9396 template <typename T, typename TypeCategory>
9497 void encode_field (const T &ext_ref, copy_operator_tag, TypeCategory);
9598
@@ -306,9 +309,9 @@ void fast_encoder_core::encode_field(const T &ext_ref, constant_operator_tag,
306309 strm_.save_previous_value (cref);
307310}
308311
309- template <typename T, typename TypeCategory >
312+ template <typename T>
310313void fast_encoder_core::encode_field (const T &ext_ref, copy_operator_tag,
311- TypeCategory ) {
314+ number_type_tag ) {
312315 encoder_presence_map &pmap = *current_;
313316 typename T::cref_type cref = ext_ref.get ();
314317
@@ -349,6 +352,52 @@ void fast_encoder_core::encode_field(const T &ext_ref, copy_operator_tag,
349352 strm_ << ext_ref;
350353}
351354
355+ template <typename T, typename TypeCategory>
356+ void fast_encoder_core::encode_field (const T &ext_ref, copy_operator_tag,
357+ TypeCategory) {
358+ encoder_presence_map &pmap = *current_;
359+ typename T::cref_type cref = ext_ref.get ();
360+
361+ value_storage previous = previous_value_of (cref);
362+
363+ if (!previous.is_defined ()) {
364+ // if the previous value is undefined – the value of the field is the
365+ // initial value
366+ // that also becomes the new previous value.
367+ // If the field has optional presence and no initial value, the field is
368+ // considered
369+ // absent and the state of the previous value is changed to empty.
370+ if (cref.is_initial_value ()) {
371+ strm_.save_previous_value (cref);
372+ pmap.set_next_bit (false );
373+ return ;
374+ }
375+ } else if (previous.is_empty ()) {
376+ // if the previous value is empty – the value of the field is empty.
377+ // If the field is optional the value is considered absent.
378+ if (!ext_ref.present ()) {
379+ strm_.save_previous_value (cref);
380+ pmap.set_next_bit (false );
381+ return ;
382+ } else if (!ext_ref.optional ()) {
383+ // It is a dynamic error [ERR D6] if the field is mandatory.
384+ BOOST_THROW_EXCEPTION (fast_dynamic_error (" D6" ));
385+
386+ // We need to handle this case because the previous value may have been
387+ // modified by another instruction with the same key and that intruction
388+ // has optional presence.
389+ }
390+ } else if (equivalent (cref, previous)) {
391+ strm_.save_previous_value (cref);
392+ pmap.set_next_bit (false );
393+ return ;
394+ }
395+
396+ strm_.save_previous_value (cref);
397+ pmap.set_next_bit (true );
398+ strm_ << ext_ref;
399+ }
400+
352401template <typename T, typename TypeCategory>
353402void fast_encoder_core::encode_field (const T &ext_ref, increment_operator_tag,
354403 TypeCategory) {
0 commit comments