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 - 2025 (C). Alex Robenko. All rights reserved.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
10
11#pragma once
12
14#include "comms/ErrorStatus.h"
15#include "comms/details/tag.h"
16#include "comms/field/basic/String.h"
17#include "comms/field/details/AdaptBasicField.h"
18#include "comms/field/details/OptionsParser.h"
19#include "comms/options.h"
20#include "comms/util/detect.h"
24
25#if COMMS_HAS_CPP17_STRING_VIEW
26#include <string_view>
27#endif // #if COMMS_HAS_CPP17_STRING_VIEW
28
29#include <vector>
30
31namespace comms
32{
33
34namespace field
35{
36
37namespace details
38{
39
40template <bool THasOrigDataViewStorage>
41struct StringOrigDataViewStorageType;
42
43template <>
44struct StringOrigDataViewStorageType<true>
45{
46#if COMMS_HAS_CPP17_STRING_VIEW
47 using Type = std::string_view;
48#else // #if COMMS_HAS_CPP17_STRING_VIEW
49 using Type = comms::util::StringView;
50#endif // #if COMMS_HAS_CPP17_STRING_VIEW
51};
52
53template <>
54struct StringOrigDataViewStorageType<false>
55{
56 using Type = std::string;
57};
58
59template <bool THasSequenceFixedSizeUseFixedSizeStorage>
60struct StringFixedSizeUseFixedSizeStorageType;
61
62template <>
63struct StringFixedSizeUseFixedSizeStorageType<true>
64{
65 template <typename TOpt>
67};
68
69template <>
70struct StringFixedSizeUseFixedSizeStorageType<false>
71{
72 template <typename TOpt>
73 using Type = typename StringOrigDataViewStorageType<TOpt::HasOrigDataView>::Type;
74};
75
76template <bool THasFixedSizeStorage>
77struct StringFixedSizeStorageType;
78
79template <>
80struct StringFixedSizeStorageType<true>
81{
82 template <typename TOpt>
84};
85
86template <>
87struct StringFixedSizeStorageType<false>
88{
89 template <typename TOpt>
90 using Type = typename StringFixedSizeUseFixedSizeStorageType<TOpt::HasSequenceFixedSizeUseFixedSizeStorage>
91 ::template Type<TOpt>;
92};
93
94template <bool THasCustomStorage>
95struct StringCustomStringStorageType;
96
97template <>
98struct StringCustomStringStorageType<true>
99{
100 template <typename TOpt>
101 using Type = typename TOpt::CustomStorageType;
102};
103
104template <>
105struct StringCustomStringStorageType<false>
106{
107 template <typename TOpt>
108 using Type =
109 typename StringFixedSizeStorageType<TOpt::HasFixedSizeStorage>::template Type<TOpt>;
110};
111
112template <typename TOpt>
113using StringStorageTypeT =
114 typename StringCustomStringStorageType<TOpt::HasCustomStorageType>::template Type<TOpt>;
115
116template <typename TFieldBase, typename... TOptions>
117using StringBase =
118 AdaptBasicFieldT<
119 basic::String<TFieldBase, StringStorageTypeT<OptionsParser<TOptions...> > >,
120 TOptions...
121 >;
122
123} // namespace details
124
158template <typename TFieldBase, typename... TOptions>
159class String : public details::StringBase<TFieldBase, TOptions...>
160{
161 using BaseImpl = details::StringBase<TFieldBase, TOptions...>;
162public:
164 using FieldBase = TFieldBase;
165
167 using Endian = typename BaseImpl::Endian;
168
170 using VersionType = typename BaseImpl::VersionType;
171
173 using ParsedOptions = details::OptionsParser<TOptions...>;
174
176 using CommsTag = typename BaseImpl::CommsTag;
177
183 using ValueType = typename BaseImpl::ValueType;
184
188 using FieldType = typename ParsedOptions::FieldType;
189
192 using SizeFieldPrefix = typename ParsedOptions::SequenceSizeFieldPrefix;
193
196 using SerLengthFieldPrefix = typename ParsedOptions::SequenceSerLengthFieldPrefix;
197
200 using TerminationFieldSuffix = typename ParsedOptions::SequenceTerminationFieldSuffix;
201
204 using TrailingFieldSuffix = typename ParsedOptions::SequenceTrailingFieldSuffix;
205
207 String() = default;
208
210 explicit String(const ValueType& val)
211 : BaseImpl(val)
212 {
213 }
214
216 explicit String(ValueType&& val)
217 : BaseImpl(std::move(val))
218 {
219 }
220
222 explicit String(const char* str)
223 {
224 setValue(str);
225 }
226
228 String(const String&) = default;
229
231 String(String&&) = default;
232
234 ~String() noexcept = default;
235
237 String& operator=(const String&) = default;
238
240 String& operator=(String&&) = default;
241
244 static constexpr bool hasFailOnInvalid()
245 {
246 return ParsedOptions::HasFailOnInvalid;
247 }
248
251 static constexpr bool hasIgnoreInvalid()
252 {
253 return ParsedOptions::HasIgnoreInvalid;
254 }
255
258 static constexpr bool hasEmptySerialization()
259 {
260 return ParsedOptions::HasEmptySerialization;
261 }
262
265 static constexpr bool hasFieldType()
266 {
267 return ParsedOptions::HasFieldType;
268 }
269
272 static constexpr bool hasSizeFieldPrefix()
273 {
274 return ParsedOptions::HasSequenceSizeFieldPrefix;
275 }
276
279 static constexpr bool hasSerLengthFieldPrefix()
280 {
281 return ParsedOptions::HasSequenceSerLengthFieldPrefix;
282 }
283
286 static constexpr bool hasTerminationFieldSuffix()
287 {
288 return ParsedOptions::HasSequenceTerminationFieldSuffix;
289 }
290
293 static constexpr bool hasTrailingFieldSuffix()
294 {
295 return ParsedOptions::HasSequenceTrailingFieldSuffix;
296 }
297
300 static constexpr bool hasFixedSize()
301 {
302 return ParsedOptions::HasSequenceFixedSize;
303 }
304
307 static constexpr bool hasFixedValue()
308 {
309 return ParsedOptions::HasFixedValue;
310 }
311
314 static constexpr bool hasName()
315 {
316 return ParsedOptions::HasName;
317 }
318
322 static constexpr std::size_t fixedSize()
323 {
324 return ParsedOptions::SequenceFixedSize;
325 }
326
337 template <typename TIter>
338 ErrorStatus read(TIter& iter, std::size_t len)
339 {
340 auto es = BaseImpl::read(iter, len);
341 using TagTmp =
342 typename comms::util::LazyShallowConditional<
343 ParsedOptions::HasSequenceFixedSize
344 >::template Type<
345 AdjustmentNeededTag,
346 NoAdjustmentTag
347 >;
348
349 adjustValue(TagTmp());
350 return es;
351 }
352
355 static constexpr bool hasReadNoStatus()
356 {
357 return BaseImpl::hasReadNoStatus();
358 }
359
365 template <typename TIter>
366 void readNoStatus(TIter& iter)
367 {
368 BaseImpl::readNoStatus(iter);
369 using TagTmp =
370 typename comms::util::LazyShallowConditional<
371 ParsedOptions::HasSequenceFixedSize
372 >::template Type<
373 AdjustmentNeededTag,
374 NoAdjustmentTag
375 >;
376
377 adjustValue(TagTmp());
378 }
379
382 {
383 return BaseImpl::value();
384 }
385
387 const ValueType& value() const
388 {
389 return BaseImpl::value();
390 }
391
394 const ValueType& getValue() const
395 {
396 return BaseImpl::getValue();
397 }
398
401 template <typename U>
402 void setValue(U&& val)
403 {
404 BaseImpl::setValue(std::forward<U>(val));
405 }
406
408 std::size_t length() const
409 {
410 return BaseImpl::length();
411 }
412
414 bool valid() const
415 {
416 return BaseImpl::valid();
417 }
418
421 bool refresh()
422 {
423 return BaseImpl::refresh();
424 }
425
427 bool canWrite() const
428 {
429 return BaseImpl::canWrite();
430 }
431
444 template <typename TIter>
445 ErrorStatus write(TIter& iter, std::size_t len) const
446 {
447 return BaseImpl::write(iter, len);
448 }
449
452 static constexpr bool hasWriteNoStatus()
453 {
454 return BaseImpl::hasWriteNoStatus();
455 }
456
462 template <typename TIter>
463 void writeNoStatus(TIter& iter) const
464 {
465 BaseImpl::writeNoStatus(iter);
466 }
467
469 static constexpr std::size_t minLength()
470 {
471 return BaseImpl::minLength();
472 }
473
475 static constexpr std::size_t maxLength()
476 {
477 return BaseImpl::maxLength();
478 }
479
485 void forceReadElemCount(std::size_t count)
486 {
487 BaseImpl::forceReadElemCount(count);
488 }
489
495 {
496 BaseImpl::clearReadElemCount();
497 }
498
503 void forceReadLength(std::size_t count)
504 {
505 return BaseImpl::forceReadLength(count);
506 }
507
513 {
514 return BaseImpl::clearReadLengthForcing();
515 }
516
518 static constexpr bool isVersionDependent()
519 {
520 return ParsedOptions::HasCustomVersionUpdate || BaseImpl::isVersionDependent();
521 }
522
524 static constexpr bool hasNonDefaultRefresh()
525 {
526 return BaseImpl::hasNonDefaultRefresh();
527 }
528
532 {
533 return BaseImpl::getVersion();
534 }
535
539 {
540 return BaseImpl::setVersion(version);
541 }
542
543protected:
544 using BaseImpl::readData;
545 using BaseImpl::writeData;
546
547private:
548 template <typename... TParams>
549 using NoAdjustmentTag = comms::details::tag::Tag1<>;
550
551 template <typename... TParams>
552 using AdjustmentNeededTag = comms::details::tag::Tag2<>;
553
554 template <typename... TParams>
555 using HasResizeTag = comms::details::tag::Tag3<>;
556
557 template <typename... TParams>
558 using HasRemoveSuffixTag = comms::details::tag::Tag4<>;
559
560 template <typename... TParams>
561 void adjustValue(NoAdjustmentTag<TParams...>)
562 {
563 }
564
565 template <typename... TParams>
566 void adjustValue(AdjustmentNeededTag<TParams...>)
567 {
568 std::size_t count = 0;
569 for (auto iter = BaseImpl::value().begin(); iter != BaseImpl::value().end(); ++iter) {
570 if (*iter == 0) {
571 break;
572 }
573 ++count;
574 }
575
576 doResize(count);
577 }
578
579 void doResize(std::size_t count)
580 {
581 using TagTmp =
583 comms::util::detect::hasResizeFunc<ValueType>()
584 >::template Type<
585 HasResizeTag<>,
587 comms::util::detect::hasRemoveSuffixFunc<ValueType>()
588 >::template Type<
589 HasRemoveSuffixTag<>,
590 void
591 >
592 >;
593
594 static_assert(!std::is_void<TagTmp>::value,
595 "The string storage value type must have either resize() or remove_suffix() "
596 "member functions");
597 doResize(count, TagTmp());
598 }
599
600 template <typename... TParams>
601 void doResize(std::size_t count, HasResizeTag<TParams...>)
602 {
603 BaseImpl::value().resize(count);
604 }
605
606 template <typename... TParams>
607 void doResize(std::size_t count, HasRemoveSuffixTag<TParams...>)
608 {
609 BaseImpl::value().remove_suffix(BaseImpl::value().size() - count);
610 }
611
612 static_assert(!ParsedOptions::HasSerOffset,
613 "comms::option::def::NumValueSerOffset option is not applicable to String field");
614 static_assert(!ParsedOptions::HasFixedLengthLimit,
615 "comms::option::def::FixedLength option is not applicable to String field");
616 static_assert(!ParsedOptions::HasFixedBitLengthLimit,
617 "comms::option::def::FixedBitLength option is not applicable to String field");
618 static_assert(!ParsedOptions::HasVarLengthLimits,
619 "comms::option::def::VarLength option is not applicable to String field");
620 static_assert(!ParsedOptions::HasAvailableLengthLimit,
621 "comms::option::def::AvailableLengthLimit option is not applicable to String field");
622 static_assert(!ParsedOptions::HasScalingRatio,
623 "comms::option::def::ScalingRatio option is not applicable to String field");
624 static_assert(!ParsedOptions::HasUnits,
625 "comms::option::def::Units option is not applicable to String field");
626 static_assert(!ParsedOptions::HasMultiRangeValidation,
627 "comms::option::def::ValidNumValueRange (or similar) option is not applicable to String field");
628 static_assert(!ParsedOptions::HasSequenceElemSerLengthFieldPrefix,
629 "comms::option::def::SequenceElemSerLengthFieldPrefix option is not applicable to String field");
630 static_assert(!ParsedOptions::HasSequenceElemFixedSerLengthFieldPrefix,
631 "comms::option::def::SequenceElemSerLengthFixedFieldPrefix option is not applicable to String field");
632 static_assert(!ParsedOptions::HasVersionsRange,
633 "comms::option::def::ExistsBetweenVersions (or similar) option is not applicable to String field");
634 static_assert(!ParsedOptions::HasMissingOnReadFail,
635 "comms::option::def::MissingOnReadFail option is not applicable to String field");
636 static_assert(!ParsedOptions::HasMissingOnInvalid,
637 "comms::option::def::MissingOnInvalid option is not applicable to String field");
638};
639
645template <typename TFieldBase, typename... TOptions>
648 const String<TFieldBase, TOptions...>& field2) noexcept
649{
650 return field1.value() == field2.value();
651}
652
658template <typename TFieldBase, typename... TOptions>
661 const String<TFieldBase, TOptions...>& field2) noexcept
662{
663 return field1.value() != field2.value();
664}
665
672template <typename TFieldBase, typename... TOptions>
675 const String<TFieldBase, TOptions...>& field2) noexcept
676{
677 return field1.value() < field2.value();
678}
679
685template <typename T>
686constexpr bool isString()
687{
688 return std::is_same<typename T::CommsTag, tag::String>::value;
689}
690
694template <typename TFieldBase, typename... TOptions>
695inline
696String<TFieldBase, TOptions...>&
698{
699 return field;
700}
701
705template <typename TFieldBase, typename... TOptions>
706inline
707const String<TFieldBase, TOptions...>&
709{
710 return field;
711}
712
713} // namespace field
714
715} // namespace comms
716
717
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:160
TFieldBase FieldBase
Base class provided in the first template parameter.
Definition String.h:164
typename ParsedOptions::SequenceTrailingFieldSuffix TrailingFieldSuffix
Type of trailing field suffix specified via comms::option::def::SequenceTrailingFieldSuffix.
Definition String.h:204
static constexpr bool hasFailOnInvalid()
Compile time inquiry of whether comms::option::def::FailOnInvalid option has been used.
Definition String.h:244
String(const ValueType &val)
Constructor.
Definition String.h:210
constexpr bool isString()
Compile time check function of whether a provided type is any variant of comms::field::String.
Definition String.h:686
typename ParsedOptions::FieldType FieldType
Type of actual extending field specified via comms::option::def::FieldType.
Definition String.h:188
static constexpr bool hasTerminationFieldSuffix()
Compile time inquiry of whether comms::option::def::SequenceTerminationFieldSuffix option has been us...
Definition String.h:286
static constexpr bool hasWriteNoStatus()
Compile time check of whether the field has proper writeNoStatus() member function.
Definition String.h:452
static constexpr bool hasFieldType()
Compile time inquiry of whether comms::option::def::FieldType option has been used.
Definition String.h:265
typename ParsedOptions::SequenceTerminationFieldSuffix TerminationFieldSuffix
Type of termination field suffix specified via comms::option::def::SequenceTerminationFieldSuffix.
Definition String.h:200
static constexpr std::size_t fixedSize()
Compile time inquiry of fixed size provided via comms::option::def::SequenceFixedSize option.
Definition String.h:322
typename ParsedOptions::SequenceSerLengthFieldPrefix SerLengthFieldPrefix
Type of length field prefix specified via comms::option::def::SequenceSerLengthFieldPrefix.
Definition String.h:196
static constexpr std::size_t minLength()
Get minimal length that is required to serialise field of this type.
Definition String.h:469
ErrorStatus read(TIter &iter, std::size_t len)
Read field value from input data sequence.
Definition String.h:338
static constexpr bool hasSerLengthFieldPrefix()
Compile time inquiry of whether comms::option::def::SequenceSerLengthFieldPrefix option has been used...
Definition String.h:279
~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:485
void setValue(U &&val)
Set value.
Definition String.h:402
bool operator!=(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Non-equality comparison operator.
Definition String.h:659
bool canWrite() const
Check of whether the field has a consistent value for writing.
Definition String.h:427
static constexpr bool hasSizeFieldPrefix()
Compile time inquiry of whether comms::option::def::SequenceSizeFieldPrefix option has been used.
Definition String.h:272
VersionType getVersion() const
Get version of the field.
Definition String.h:531
void forceReadLength(std::size_t count)
Force available length for the next read() invocation.
Definition String.h:503
static constexpr bool hasFixedValue()
Compile time inquiry of whether comms::option::def::FixedValue option has been used.
Definition String.h:307
bool setVersion(VersionType version)
Default implementation of version update.
Definition String.h:538
ErrorStatus write(TIter &iter, std::size_t len) const
Write current field value to output data sequence.
Definition String.h:445
static constexpr bool hasIgnoreInvalid()
Compile time inquiry of whether comms::option::def::IgnoreInvalid option has been used.
Definition String.h:251
void clearReadElemCount()
Clear forcing of the number of characters that must be read in the next read() invocation.
Definition String.h:494
const ValueType & getValue() const
Get value.
Definition String.h:394
bool operator<(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition String.h:673
typename BaseImpl::CommsTag CommsTag
Tag indicating type of the field.
Definition String.h:176
static constexpr bool hasReadNoStatus()
Compile time check of whether the field has proper readNoStatus() member function.
Definition String.h:355
typename BaseImpl::ValueType ValueType
Type of underlying value.
Definition String.h:183
bool valid() const
Check validity of the field value.
Definition String.h:414
static constexpr bool hasFixedSize()
Compile time inquiry of whether comms::option::def::SequenceFixedSize option has been used.
Definition String.h:300
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:697
bool refresh()
Refresh the field's value.
Definition String.h:421
String(const char *str)
Constructor.
Definition String.h:222
String()=default
Default constructor.
typename BaseImpl::VersionType VersionType
Version type.
Definition String.h:170
String(String &&)=default
Move constructor.
std::size_t length() const
Get length of serialised data.
Definition String.h:408
details::OptionsParser< TOptions... > ParsedOptions
All the options provided to this class bundled into struct.
Definition String.h:173
static constexpr bool hasEmptySerialization()
Compile time inquiry of whether comms::option::def::EmptySerialization option has been used.
Definition String.h:258
typename BaseImpl::Endian Endian
Endian used for serialisation.
Definition String.h:167
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:708
static constexpr bool hasNonDefaultRefresh()
Compile time check if this class has non-default refresh functionality.
Definition String.h:524
String(ValueType &&val)
Constructor.
Definition String.h:216
typename ParsedOptions::SequenceSizeFieldPrefix SizeFieldPrefix
Type of size field prefix specified via comms::option::def::SequenceSizeFieldPrefix.
Definition String.h:192
void clearReadLengthForcing()
Clear forcing of the available length in the next read() invocation.
Definition String.h:512
ValueType & value()
Get access to the value storage.
Definition String.h:381
static constexpr bool hasTrailingFieldSuffix()
Compile time inquiry of whether comms::option::def::SequenceTrailingFieldSuffix option has been used.
Definition String.h:293
const ValueType & value() const
Get access to the value storage.
Definition String.h:387
void writeNoStatus(TIter &iter) const
Write current field value to output data sequence without error check and status report.
Definition String.h:463
static constexpr std::size_t maxLength()
Get maximal length that is required to serialise field of this type.
Definition String.h:475
void readNoStatus(TIter &iter)
Read field value from input data sequence without error check and status report.
Definition String.h:366
bool operator==(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Equality comparison operator.
Definition String.h:646
static constexpr bool isVersionDependent()
Compile time check if this class is version dependent.
Definition String.h:518
static constexpr bool hasName()
Compile time inquiry of whether comms::option::def::HasName option has been used.
Definition String.h:314
Replacement to std::string when no dynamic memory allocation is allowed.
Definition StaticString.h:789
Describes an object that can refer to a constant contiguous sequence of char-like objects with the fi...
Definition StringView.h:35
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
constexpr unsigned version()
Version of the COMMS library as single numeric value.
Definition version.h:64
STL namespace.
Contains definition of all the options used by the COMMS library.
Replacement to std::conditional.
Definition type_traits.h:29
Replacement to some types from standard type_traits.
Various compile-time detection functions of whether specific member functions and/or types exist.