COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
String.h
Go to the documentation of this file.
1//
2// Copyright 2015 - 2026 (C). Alex Robenko. All rights reserved.
3//
4// SPDX-License-Identifier: MPL-2.0
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
12
13#pragma once
14
16#include "comms/ErrorStatus.h"
17#include "comms/details/tag.h"
18#include "comms/field/basic/String.h"
19#include "comms/field/details/AdaptBasicField.h"
20#include "comms/field/details/OptionsParser.h"
21#include "comms/options.h"
22#include "comms/util/detect.h"
26
27#include <cstddef>
28#include <string>
29#include <type_traits>
30#include <utility>
31
32#if COMMS_HAS_CPP17_STRING_VIEW
33#include <string_view>
34#endif // #if COMMS_HAS_CPP17_STRING_VIEW
35
36#include <utility>
37#include <vector>
38
39namespace comms
40{
41
42namespace field
43{
44
45namespace details
46{
47
48template <bool THasOrigDataViewStorage>
49struct StringOrigDataViewStorageType;
50
51template <>
52struct StringOrigDataViewStorageType<true>
53{
54#if COMMS_HAS_CPP17_STRING_VIEW
55 using Type = std::string_view;
56#else // #if COMMS_HAS_CPP17_STRING_VIEW
57 using Type = comms::util::StringView;
58#endif // #if COMMS_HAS_CPP17_STRING_VIEW
59};
60
61template <>
62struct StringOrigDataViewStorageType<false>
63{
64 using Type = std::string;
65};
66
67template <bool THasSequenceFixedSizeUseFixedSizeStorage>
68struct StringFixedSizeUseFixedSizeStorageType;
69
70template <>
71struct StringFixedSizeUseFixedSizeStorageType<true>
72{
73 template <typename TOpt>
75};
76
77template <>
78struct StringFixedSizeUseFixedSizeStorageType<false>
79{
80 template <typename TOpt>
81 using Type = typename StringOrigDataViewStorageType<TOpt::HasOrigDataView>::Type;
82};
83
84template <bool THasFixedSizeStorage>
85struct StringFixedSizeStorageType;
86
87template <>
88struct StringFixedSizeStorageType<true>
89{
90 template <typename TOpt>
92};
93
94template <>
95struct StringFixedSizeStorageType<false>
96{
97 template <typename TOpt>
98 using Type = typename StringFixedSizeUseFixedSizeStorageType<TOpt::HasSequenceFixedSizeUseFixedSizeStorage>
99 ::template Type<TOpt>;
100};
101
102template <bool THasCustomStorage>
103struct StringCustomStringStorageType;
104
105template <>
106struct StringCustomStringStorageType<true>
107{
108 template <typename TOpt>
109 using Type = typename TOpt::CustomStorageType;
110};
111
112template <>
113struct StringCustomStringStorageType<false>
114{
115 template <typename TOpt>
116 using Type =
117 typename StringFixedSizeStorageType<TOpt::HasFixedSizeStorage>::template Type<TOpt>;
118};
119
120template <typename TOpt>
121using StringStorageTypeT =
122 typename StringCustomStringStorageType<TOpt::HasCustomStorageType>::template Type<TOpt>;
123
124template <typename TFieldBase, typename... TOptions>
125using StringBase =
126 AdaptBasicFieldT<
127 basic::String<TFieldBase, StringStorageTypeT<OptionsParser<TOptions...> > >,
128 TOptions...
129 >;
130
131} // namespace details
132
166template <typename TFieldBase, typename... TOptions>
167class String : public details::StringBase<TFieldBase, TOptions...>
168{
169 using BaseImpl = details::StringBase<TFieldBase, TOptions...>;
170public:
172 using FieldBase = TFieldBase;
173
175 using Endian = typename BaseImpl::Endian;
176
178 using VersionType = typename BaseImpl::VersionType;
179
181 using ParsedOptions = details::OptionsParser<TOptions...>;
182
184 using CommsTag = typename BaseImpl::CommsTag;
185
191 using ValueType = typename BaseImpl::ValueType;
192
196 using FieldType = typename ParsedOptions::FieldType;
197
200 using SizeFieldPrefix = typename ParsedOptions::SequenceSizeFieldPrefix;
201
204 using SerLengthFieldPrefix = typename ParsedOptions::SequenceSerLengthFieldPrefix;
205
208 using TerminationFieldSuffix = typename ParsedOptions::SequenceTerminationFieldSuffix;
209
212 using TrailingFieldSuffix = typename ParsedOptions::SequenceTrailingFieldSuffix;
213
215 String() = default;
216
218 explicit String(const ValueType& val)
219 : BaseImpl(val)
220 {
221 }
222
224 explicit String(ValueType&& val)
225 : BaseImpl(std::move(val))
226 {
227 }
228
230 explicit String(const char* str)
231 {
232 setValue(str);
233 }
234
236 String(const String&) = default;
237
239 String(String&&) = default;
240
242 ~String() noexcept = default;
243
245 String& operator=(const String&) = default;
246
248 String& operator=(String&&) = default;
249
252 static constexpr bool hasFailOnInvalid()
253 {
254 return ParsedOptions::HasFailOnInvalid;
255 }
256
259 static constexpr bool hasIgnoreInvalid()
260 {
261 return ParsedOptions::HasIgnoreInvalid;
262 }
263
266 static constexpr bool hasEmptySerialization()
267 {
268 return ParsedOptions::HasEmptySerialization;
269 }
270
273 static constexpr bool hasFieldType()
274 {
275 return ParsedOptions::HasFieldType;
276 }
277
280 static constexpr bool hasSizeFieldPrefix()
281 {
282 return ParsedOptions::HasSequenceSizeFieldPrefix;
283 }
284
287 static constexpr bool hasSerLengthFieldPrefix()
288 {
289 return ParsedOptions::HasSequenceSerLengthFieldPrefix;
290 }
291
294 static constexpr bool hasTerminationFieldSuffix()
295 {
296 return ParsedOptions::HasSequenceTerminationFieldSuffix;
297 }
298
301 static constexpr bool hasTrailingFieldSuffix()
302 {
303 return ParsedOptions::HasSequenceTrailingFieldSuffix;
304 }
305
308 static constexpr bool hasFixedSize()
309 {
310 return ParsedOptions::HasSequenceFixedSize;
311 }
312
315 static constexpr bool hasFixedValue()
316 {
317 return ParsedOptions::HasFixedValue;
318 }
319
322 static constexpr bool hasName()
323 {
324 return ParsedOptions::HasName;
325 }
326
330 static constexpr std::size_t fixedSize()
331 {
332 return ParsedOptions::SequenceFixedSize;
333 }
334
345 template <typename TIter>
346 ErrorStatus read(TIter& iter, std::size_t len)
347 {
348 auto es = BaseImpl::read(iter, len);
349 using TagTmp =
350 typename comms::util::LazyShallowConditional<
351 ParsedOptions::HasSequenceFixedSize
352 >::template Type<
353 AdjustmentNeededTag,
354 NoAdjustmentTag
355 >;
356
357 adjustValue(TagTmp());
358 return es;
359 }
360
363 static constexpr bool hasReadNoStatus()
364 {
365 return BaseImpl::hasReadNoStatus();
366 }
367
373 template <typename TIter>
374 void readNoStatus(TIter& iter)
375 {
376 BaseImpl::readNoStatus(iter);
377 using TagTmp =
378 typename comms::util::LazyShallowConditional<
379 ParsedOptions::HasSequenceFixedSize
380 >::template Type<
381 AdjustmentNeededTag,
382 NoAdjustmentTag
383 >;
384
385 adjustValue(TagTmp());
386 }
387
390 {
391 return BaseImpl::value();
392 }
393
395 const ValueType& value() const
396 {
397 return BaseImpl::value();
398 }
399
402 const ValueType& getValue() const
403 {
404 return BaseImpl::getValue();
405 }
406
409 template <typename U>
410 void setValue(U&& val)
411 {
412 BaseImpl::setValue(std::forward<U>(val));
413 }
414
416 std::size_t length() const
417 {
418 return BaseImpl::length();
419 }
420
422 bool valid() const
423 {
424 return BaseImpl::valid();
425 }
426
429 bool refresh()
430 {
431 return BaseImpl::refresh();
432 }
433
435 bool canWrite() const
436 {
437 return BaseImpl::canWrite();
438 }
439
452 template <typename TIter>
453 ErrorStatus write(TIter& iter, std::size_t len) const
454 {
455 return BaseImpl::write(iter, len);
456 }
457
460 static constexpr bool hasWriteNoStatus()
461 {
462 return BaseImpl::hasWriteNoStatus();
463 }
464
470 template <typename TIter>
471 void writeNoStatus(TIter& iter) const
472 {
473 BaseImpl::writeNoStatus(iter);
474 }
475
477 static constexpr std::size_t minLength()
478 {
479 return BaseImpl::minLength();
480 }
481
483 static constexpr std::size_t maxLength()
484 {
485 return BaseImpl::maxLength();
486 }
487
493 void forceReadElemCount(std::size_t count)
494 {
495 BaseImpl::forceReadElemCount(count);
496 }
497
503 {
504 BaseImpl::clearReadElemCount();
505 }
506
511 void forceReadLength(std::size_t count)
512 {
513 return BaseImpl::forceReadLength(count);
514 }
515
521 {
522 return BaseImpl::clearReadLengthForcing();
523 }
524
526 static constexpr bool isVersionDependent()
527 {
528 return ParsedOptions::HasCustomVersionUpdate || BaseImpl::isVersionDependent();
529 }
530
532 static constexpr bool hasNonDefaultRefresh()
533 {
534 return BaseImpl::hasNonDefaultRefresh();
535 }
536
540 {
541 return BaseImpl::getVersion();
542 }
543
547 {
548 return BaseImpl::setVersion(version);
549 }
550
551protected:
552 using BaseImpl::readData;
553 using BaseImpl::writeData;
554
555private:
556 template <typename... TParams>
557 using NoAdjustmentTag = comms::details::tag::Tag1<>;
558
559 template <typename... TParams>
560 using AdjustmentNeededTag = comms::details::tag::Tag2<>;
561
562 template <typename... TParams>
563 using HasResizeTag = comms::details::tag::Tag3<>;
564
565 template <typename... TParams>
566 using HasRemoveSuffixTag = comms::details::tag::Tag4<>;
567
568 template <typename... TParams>
569 void adjustValue(NoAdjustmentTag<TParams...>)
570 {
571 }
572
573 template <typename... TParams>
574 void adjustValue(AdjustmentNeededTag<TParams...>)
575 {
576 std::size_t count = 0;
577 for (auto iter = BaseImpl::value().begin(); iter != BaseImpl::value().end(); ++iter) {
578 if (*iter == 0) {
579 break;
580 }
581 ++count;
582 }
583
584 doResize(count);
585 }
586
587 void doResize(std::size_t count)
588 {
589 using TagTmp =
591 comms::util::detect::hasResizeFunc<ValueType>()
592 >::template Type<
593 HasResizeTag<>,
595 comms::util::detect::hasRemoveSuffixFunc<ValueType>()
596 >::template Type<
597 HasRemoveSuffixTag<>,
598 void
599 >
600 >;
601
602 static_assert(!std::is_void<TagTmp>::value,
603 "The string storage value type must have either resize() or remove_suffix() "
604 "member functions");
605 doResize(count, TagTmp());
606 }
607
608 template <typename... TParams>
609 void doResize(std::size_t count, HasResizeTag<TParams...>)
610 {
611 BaseImpl::value().resize(count);
612 }
613
614 template <typename... TParams>
615 void doResize(std::size_t count, HasRemoveSuffixTag<TParams...>)
616 {
617 BaseImpl::value().remove_suffix(BaseImpl::value().size() - count);
618 }
619
620 static_assert(!ParsedOptions::HasSerOffset,
621 "comms::option::def::NumValueSerOffset option is not applicable to String field");
622 static_assert(!ParsedOptions::HasFixedLengthLimit,
623 "comms::option::def::FixedLength option is not applicable to String field");
624 static_assert(!ParsedOptions::HasFixedBitLengthLimit,
625 "comms::option::def::FixedBitLength option is not applicable to String field");
626 static_assert(!ParsedOptions::HasVarLengthLimits,
627 "comms::option::def::VarLength option is not applicable to String field");
628 static_assert(!ParsedOptions::HasAvailableLengthLimit,
629 "comms::option::def::AvailableLengthLimit option is not applicable to String field");
630 static_assert(!ParsedOptions::HasScalingRatio,
631 "comms::option::def::ScalingRatio option is not applicable to String field");
632 static_assert(!ParsedOptions::HasUnits,
633 "comms::option::def::Units option is not applicable to String field");
634 static_assert(!ParsedOptions::HasMultiRangeValidation,
635 "comms::option::def::ValidNumValueRange (or similar) option is not applicable to String field");
636 static_assert(!ParsedOptions::HasSequenceElemSerLengthFieldPrefix,
637 "comms::option::def::SequenceElemSerLengthFieldPrefix option is not applicable to String field");
638 static_assert(!ParsedOptions::HasSequenceElemFixedSerLengthFieldPrefix,
639 "comms::option::def::SequenceElemSerLengthFixedFieldPrefix option is not applicable to String field");
640 static_assert(!ParsedOptions::HasVersionsRange,
641 "comms::option::def::ExistsBetweenVersions (or similar) option is not applicable to String field");
642 static_assert(!ParsedOptions::HasMissingOnReadFail,
643 "comms::option::def::MissingOnReadFail option is not applicable to String field");
644 static_assert(!ParsedOptions::HasMissingOnInvalid,
645 "comms::option::def::MissingOnInvalid option is not applicable to String field");
646};
647
653template <typename TFieldBase, typename... TOptions>
656 const String<TFieldBase, TOptions...>& field2) noexcept
657{
658 return field1.value() == field2.value();
659}
660
666template <typename TFieldBase, typename... TOptions>
669 const String<TFieldBase, TOptions...>& field2) noexcept
670{
671 return field1.value() != field2.value();
672}
673
680template <typename TFieldBase, typename... TOptions>
683 const String<TFieldBase, TOptions...>& field2) noexcept
684{
685 return field1.value() < field2.value();
686}
687
693template <typename T>
694constexpr bool isString()
695{
696 return std::is_same<typename T::CommsTag, tag::String>::value;
697}
698
702template <typename TFieldBase, typename... TOptions>
703inline
704String<TFieldBase, TOptions...>&
706{
707 return field;
708}
709
713template <typename TFieldBase, typename... TOptions>
714inline
715const String<TFieldBase, TOptions...>&
717{
718 return field;
719}
720
721} // namespace field
722
723} // namespace comms
724
Contains various compiler related definitions.
This file contain definition of error statuses used by comms module.
Contains comms::util::StaticString class.
Contains comms::util::StringView class.
Field that represents a string.
Definition String.h:168
TFieldBase FieldBase
Base class provided in the first template parameter.
Definition String.h:172
typename ParsedOptions::SequenceTrailingFieldSuffix TrailingFieldSuffix
Type of trailing field suffix specified via comms::option::def::SequenceTrailingFieldSuffix.
Definition String.h:212
static constexpr bool hasFailOnInvalid()
Compile time inquiry of whether comms::option::def::FailOnInvalid option has been used.
Definition String.h:252
String(const ValueType &val)
Constructor.
Definition String.h:218
constexpr bool isString()
Compile time check function of whether a provided type is any variant of comms::field::String.
Definition String.h:694
typename ParsedOptions::FieldType FieldType
Type of actual extending field specified via comms::option::def::FieldType.
Definition String.h:196
static constexpr bool hasTerminationFieldSuffix()
Compile time inquiry of whether comms::option::def::SequenceTerminationFieldSuffix option has been us...
Definition String.h:294
static constexpr bool hasWriteNoStatus()
Compile time check of whether the field has proper writeNoStatus() member function.
Definition String.h:460
static constexpr bool hasFieldType()
Compile time inquiry of whether comms::option::def::FieldType option has been used.
Definition String.h:273
typename ParsedOptions::SequenceTerminationFieldSuffix TerminationFieldSuffix
Type of termination field suffix specified via comms::option::def::SequenceTerminationFieldSuffix.
Definition String.h:208
static constexpr std::size_t fixedSize()
Compile time inquiry of fixed size provided via comms::option::def::SequenceFixedSize option.
Definition String.h:330
typename ParsedOptions::SequenceSerLengthFieldPrefix SerLengthFieldPrefix
Type of length field prefix specified via comms::option::def::SequenceSerLengthFieldPrefix.
Definition String.h:204
static constexpr std::size_t minLength()
Get minimal length that is required to serialise field of this type.
Definition String.h:477
ErrorStatus read(TIter &iter, std::size_t len)
Read field value from input data sequence.
Definition String.h:346
static constexpr bool hasSerLengthFieldPrefix()
Compile time inquiry of whether comms::option::def::SequenceSerLengthFieldPrefix option has been used...
Definition String.h:287
~String() noexcept=default
Destructor.
void forceReadElemCount(std::size_t count)
Force number of characters that must be read in the next read() invocation.
Definition String.h:493
void setValue(U &&val)
Set value.
Definition String.h:410
bool operator!=(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Non-equality comparison operator.
Definition String.h:667
bool canWrite() const
Check of whether the field has a consistent value for writing.
Definition String.h:435
static constexpr bool hasSizeFieldPrefix()
Compile time inquiry of whether comms::option::def::SequenceSizeFieldPrefix option has been used.
Definition String.h:280
VersionType getVersion() const
Get version of the field.
Definition String.h:539
void forceReadLength(std::size_t count)
Force available length for the next read() invocation.
Definition String.h:511
static constexpr bool hasFixedValue()
Compile time inquiry of whether comms::option::def::FixedValue option has been used.
Definition String.h:315
bool setVersion(VersionType version)
Default implementation of version update.
Definition String.h:546
ErrorStatus write(TIter &iter, std::size_t len) const
Write current field value to output data sequence.
Definition String.h:453
static constexpr bool hasIgnoreInvalid()
Compile time inquiry of whether comms::option::def::IgnoreInvalid option has been used.
Definition String.h:259
void clearReadElemCount()
Clear forcing of the number of characters that must be read in the next read() invocation.
Definition String.h:502
const ValueType & getValue() const
Get value.
Definition String.h:402
bool operator<(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition String.h:681
typename BaseImpl::CommsTag CommsTag
Tag indicating type of the field.
Definition String.h:184
static constexpr bool hasReadNoStatus()
Compile time check of whether the field has proper readNoStatus() member function.
Definition String.h:363
typename BaseImpl::ValueType ValueType
Type of underlying value.
Definition String.h:191
bool valid() const
Check validity of the field value.
Definition String.h:422
static constexpr bool hasFixedSize()
Compile time inquiry of whether comms::option::def::SequenceFixedSize option has been used.
Definition String.h:308
String< TFieldBase, TOptions... > & toFieldBase(String< TFieldBase, TOptions... > &field)
Upcast type of the field definition to its parent comms::field::String type in order to have access t...
Definition String.h:705
bool refresh()
Refresh the field's value.
Definition String.h:429
String(const char *str)
Constructor.
Definition String.h:230
String()=default
Default constructor.
typename BaseImpl::VersionType VersionType
Version type.
Definition String.h:178
String(String &&)=default
Move constructor.
std::size_t length() const
Get length of serialised data.
Definition String.h:416
details::OptionsParser< TOptions... > ParsedOptions
All the options provided to this class bundled into struct.
Definition String.h:181
static constexpr bool hasEmptySerialization()
Compile time inquiry of whether comms::option::def::EmptySerialization option has been used.
Definition String.h:266
typename BaseImpl::Endian Endian
Endian used for serialisation.
Definition String.h:175
String(const String &)=default
Copy constructor.
const String< TFieldBase, TOptions... > & toFieldBase(const String< TFieldBase, TOptions... > &field)
Upcast type of the field definition to its parent comms::field::String type in order to have access t...
Definition String.h:716
static constexpr bool hasNonDefaultRefresh()
Compile time check if this class has non-default refresh functionality.
Definition String.h:532
String(ValueType &&val)
Constructor.
Definition String.h:224
typename ParsedOptions::SequenceSizeFieldPrefix SizeFieldPrefix
Type of size field prefix specified via comms::option::def::SequenceSizeFieldPrefix.
Definition String.h:200
void clearReadLengthForcing()
Clear forcing of the available length in the next read() invocation.
Definition String.h:520
ValueType & value()
Get access to the value storage.
Definition String.h:389
static constexpr bool hasTrailingFieldSuffix()
Compile time inquiry of whether comms::option::def::SequenceTrailingFieldSuffix option has been used.
Definition String.h:301
const ValueType & value() const
Get access to the value storage.
Definition String.h:395
void writeNoStatus(TIter &iter) const
Write current field value to output data sequence without error check and status report.
Definition String.h:471
static constexpr std::size_t maxLength()
Get maximal length that is required to serialise field of this type.
Definition String.h:483
void readNoStatus(TIter &iter)
Read field value from input data sequence without error check and status report.
Definition String.h:374
bool operator==(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Equality comparison operator.
Definition String.h:654
static constexpr bool isVersionDependent()
Compile time check if this class is version dependent.
Definition String.h:526
static constexpr bool hasName()
Compile time inquiry of whether comms::option::def::HasName option has been used.
Definition String.h:322
Replacement to std::string when no dynamic memory allocation is allowed.
Definition StaticString.h:791
Describes an object that can refer to a constant contiguous sequence of char-like objects with the fi...
Definition StringView.h:37
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:19
constexpr unsigned version()
Version of the COMMS library as single numeric value.
Definition version.h:66
STL namespace.
Contains definition of all the options used by the COMMS library.
Replacement to std::conditional.
Definition type_traits.h:32
Replacement to some types from standard type_traits.
Various compile-time detection functions of whether specific member functions and/or types exist.