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
13#include <vector>
14
16
17#if COMMS_HAS_CPP17_STRING_VIEW
18#include <string_view>
19#endif // #if COMMS_HAS_CPP17_STRING_VIEW
20
21#include "comms/ErrorStatus.h"
22#include "comms/options.h"
25#include "comms/util/detect.h"
27#include "comms/field/basic/String.h"
28#include "comms/field/details/AdaptBasicField.h"
29#include "comms/field/details/OptionsParser.h"
30#include "comms/details/tag.h"
31
32namespace comms
33{
34
35namespace field
36{
37
38namespace details
39{
40
41template <bool THasOrigDataViewStorage>
42struct StringOrigDataViewStorageType;
43
44template <>
45struct StringOrigDataViewStorageType<true>
46{
47#if COMMS_HAS_CPP17_STRING_VIEW
48 using Type = std::string_view;
49#else // #if COMMS_HAS_CPP17_STRING_VIEW
50 using Type = comms::util::StringView;
51#endif // #if COMMS_HAS_CPP17_STRING_VIEW
52};
53
54template <>
55struct StringOrigDataViewStorageType<false>
56{
57 using Type = std::string;
58};
59
60template <bool THasSequenceFixedSizeUseFixedSizeStorage>
61struct StringFixedSizeUseFixedSizeStorageType;
62
63template <>
64struct StringFixedSizeUseFixedSizeStorageType<true>
65{
66 template <typename TOpt>
68};
69
70template <>
71struct StringFixedSizeUseFixedSizeStorageType<false>
72{
73 template <typename TOpt>
74 using Type = typename StringOrigDataViewStorageType<TOpt::HasOrigDataView>::Type;
75};
76
77template <bool THasFixedSizeStorage>
78struct StringFixedSizeStorageType;
79
80template <>
81struct StringFixedSizeStorageType<true>
82{
83 template <typename TOpt>
85};
86
87template <>
88struct StringFixedSizeStorageType<false>
89{
90 template <typename TOpt>
91 using Type = typename StringFixedSizeUseFixedSizeStorageType<TOpt::HasSequenceFixedSizeUseFixedSizeStorage>
92 ::template Type<TOpt>;
93};
94
95template <bool THasCustomStorage>
96struct StringCustomStringStorageType;
97
98template <>
99struct StringCustomStringStorageType<true>
100{
101 template <typename TOpt>
102 using Type = typename TOpt::CustomStorageType;
103};
104
105template <>
106struct StringCustomStringStorageType<false>
107{
108 template <typename TOpt>
109 using Type =
110 typename StringFixedSizeStorageType<TOpt::HasFixedSizeStorage>::template Type<TOpt>;
111};
112
113template <typename TOpt>
114using StringStorageTypeT =
115 typename StringCustomStringStorageType<TOpt::HasCustomStorageType>::template Type<TOpt>;
116
117template <typename TFieldBase, typename... TOptions>
118using StringBase =
119 AdaptBasicFieldT<
120 basic::String<TFieldBase, StringStorageTypeT<OptionsParser<TOptions...> > >,
121 TOptions...
122 >;
123
124} // namespace details
125
159template <typename TFieldBase, typename... TOptions>
160class String : public details::StringBase<TFieldBase, TOptions...>
161{
162 using BaseImpl = details::StringBase<TFieldBase, TOptions...>;
163public:
165 using FieldBase = TFieldBase;
166
168 using Endian = typename BaseImpl::Endian;
169
171 using VersionType = typename BaseImpl::VersionType;
172
174 using ParsedOptions = details::OptionsParser<TOptions...>;
175
177 using CommsTag = typename BaseImpl::CommsTag;
178
184 using ValueType = typename BaseImpl::ValueType;
185
189 using FieldType = typename ParsedOptions::FieldType;
190
193 using SizeFieldPrefix = typename ParsedOptions::SequenceSizeFieldPrefix;
194
197 using SerLengthFieldPrefix = typename ParsedOptions::SequenceSerLengthFieldPrefix;
198
201 using TerminationFieldSuffix = typename ParsedOptions::SequenceTerminationFieldSuffix;
202
205 using TrailingFieldSuffix = typename ParsedOptions::SequenceTrailingFieldSuffix;
206
208 String() = default;
209
211 explicit String(const ValueType& val)
212 : BaseImpl(val)
213 {
214 }
215
217 explicit String(ValueType&& val)
218 : BaseImpl(std::move(val))
219 {
220 }
221
223 explicit String(const char* str)
224 {
225 setValue(str);
226 }
227
229 String(const String&) = default;
230
232 String(String&&) = default;
233
235 ~String() noexcept = default;
236
238 String& operator=(const String&) = default;
239
241 String& operator=(String&&) = default;
242
245 static constexpr bool hasFailOnInvalid()
246 {
247 return ParsedOptions::HasFailOnInvalid;
248 }
249
252 static constexpr bool hasIgnoreInvalid()
253 {
254 return ParsedOptions::HasIgnoreInvalid;
255 }
256
259 static constexpr bool hasEmptySerialization()
260 {
261 return ParsedOptions::HasEmptySerialization;
262 }
263
266 static constexpr bool hasFieldType()
267 {
268 return ParsedOptions::HasFieldType;
269 }
270
273 static constexpr bool hasSizeFieldPrefix()
274 {
275 return ParsedOptions::HasSequenceSizeFieldPrefix;
276 }
277
280 static constexpr bool hasSerLengthFieldPrefix()
281 {
282 return ParsedOptions::HasSequenceSerLengthFieldPrefix;
283 }
284
287 static constexpr bool hasTerminationFieldSuffix()
288 {
289 return ParsedOptions::HasSequenceTerminationFieldSuffix;
290 }
291
294 static constexpr bool hasTrailingFieldSuffix()
295 {
296 return ParsedOptions::HasSequenceTrailingFieldSuffix;
297 }
298
301 static constexpr bool hasFixedSize()
302 {
303 return ParsedOptions::HasSequenceFixedSize;
304 }
305
308 static constexpr bool hasFixedValue()
309 {
310 return ParsedOptions::HasFixedValue;
311 }
312
315 static constexpr bool hasName()
316 {
317 return ParsedOptions::HasName;
318 }
319
323 static constexpr std::size_t fixedSize()
324 {
325 return ParsedOptions::SequenceFixedSize;
326 }
327
338 template <typename TIter>
339 ErrorStatus read(TIter& iter, std::size_t len)
340 {
341 auto es = BaseImpl::read(iter, len);
342 using TagTmp =
343 typename comms::util::LazyShallowConditional<
344 ParsedOptions::HasSequenceFixedSize
345 >::template Type<
346 AdjustmentNeededTag,
347 NoAdjustmentTag
348 >;
349
350 adjustValue(TagTmp());
351 return es;
352 }
353
356 static constexpr bool hasReadNoStatus()
357 {
358 return BaseImpl::hasReadNoStatus();
359 }
360
366 template <typename TIter>
367 void readNoStatus(TIter& iter)
368 {
369 BaseImpl::readNoStatus(iter);
370 using TagTmp =
371 typename comms::util::LazyShallowConditional<
372 ParsedOptions::HasSequenceFixedSize
373 >::template Type<
374 AdjustmentNeededTag,
375 NoAdjustmentTag
376 >;
377
378 adjustValue(TagTmp());
379 }
380
383 {
384 return BaseImpl::value();
385 }
386
388 const ValueType& value() const
389 {
390 return BaseImpl::value();
391 }
392
395 const ValueType& getValue() const
396 {
397 return BaseImpl::getValue();
398 }
399
402 template <typename U>
403 void setValue(U&& val)
404 {
405 BaseImpl::setValue(std::forward<U>(val));
406 }
407
409 std::size_t length() const
410 {
411 return BaseImpl::length();
412 }
413
415 bool valid() const
416 {
417 return BaseImpl::valid();
418 }
419
422 bool refresh()
423 {
424 return BaseImpl::refresh();
425 }
426
428 bool canWrite() const
429 {
430 return BaseImpl::canWrite();
431 }
432
445 template <typename TIter>
446 ErrorStatus write(TIter& iter, std::size_t len) const
447 {
448 return BaseImpl::write(iter, len);
449 }
450
453 static constexpr bool hasWriteNoStatus()
454 {
455 return BaseImpl::hasWriteNoStatus();
456 }
457
463 template <typename TIter>
464 void writeNoStatus(TIter& iter) const
465 {
466 BaseImpl::writeNoStatus(iter);
467 }
468
470 static constexpr std::size_t minLength()
471 {
472 return BaseImpl::minLength();
473 }
474
476 static constexpr std::size_t maxLength()
477 {
478 return BaseImpl::maxLength();
479 }
480
486 void forceReadElemCount(std::size_t count)
487 {
488 BaseImpl::forceReadElemCount(count);
489 }
490
496 {
497 BaseImpl::clearReadElemCount();
498 }
499
504 void forceReadLength(std::size_t count)
505 {
506 return BaseImpl::forceReadLength(count);
507 }
508
514 {
515 return BaseImpl::clearReadLengthForcing();
516 }
517
519 static constexpr bool isVersionDependent()
520 {
521 return ParsedOptions::HasCustomVersionUpdate || BaseImpl::isVersionDependent();
522 }
523
525 static constexpr bool hasNonDefaultRefresh()
526 {
527 return BaseImpl::hasNonDefaultRefresh();
528 }
529
533 {
534 return BaseImpl::getVersion();
535 }
536
540 {
541 return BaseImpl::setVersion(version);
542 }
543
544protected:
545 using BaseImpl::readData;
546 using BaseImpl::writeData;
547
548private:
549 template <typename... TParams>
550 using NoAdjustmentTag = comms::details::tag::Tag1<>;
551
552 template <typename... TParams>
553 using AdjustmentNeededTag = comms::details::tag::Tag2<>;
554
555 template <typename... TParams>
556 using HasResizeTag = comms::details::tag::Tag3<>;
557
558 template <typename... TParams>
559 using HasRemoveSuffixTag = comms::details::tag::Tag4<>;
560
561 template <typename... TParams>
562 void adjustValue(NoAdjustmentTag<TParams...>)
563 {
564 }
565
566 template <typename... TParams>
567 void adjustValue(AdjustmentNeededTag<TParams...>)
568 {
569 std::size_t count = 0;
570 for (auto iter = BaseImpl::value().begin(); iter != BaseImpl::value().end(); ++iter) {
571 if (*iter == 0) {
572 break;
573 }
574 ++count;
575 }
576
577 doResize(count);
578 }
579
580 void doResize(std::size_t count)
581 {
582 using TagTmp =
584 comms::util::detect::hasResizeFunc<ValueType>()
585 >::template Type<
586 HasResizeTag<>,
588 comms::util::detect::hasRemoveSuffixFunc<ValueType>()
589 >::template Type<
590 HasRemoveSuffixTag<>,
591 void
592 >
593 >;
594
595 static_assert(!std::is_void<TagTmp>::value,
596 "The string storage value type must have either resize() or remove_suffix() "
597 "member functions");
598 doResize(count, TagTmp());
599 }
600
601 template <typename... TParams>
602 void doResize(std::size_t count, HasResizeTag<TParams...>)
603 {
604 BaseImpl::value().resize(count);
605 }
606
607 template <typename... TParams>
608 void doResize(std::size_t count, HasRemoveSuffixTag<TParams...>)
609 {
610 BaseImpl::value().remove_suffix(BaseImpl::value().size() - count);
611 }
612
613 static_assert(!ParsedOptions::HasSerOffset,
614 "comms::option::def::NumValueSerOffset option is not applicable to String field");
615 static_assert(!ParsedOptions::HasFixedLengthLimit,
616 "comms::option::def::FixedLength option is not applicable to String field");
617 static_assert(!ParsedOptions::HasFixedBitLengthLimit,
618 "comms::option::def::FixedBitLength option is not applicable to String field");
619 static_assert(!ParsedOptions::HasVarLengthLimits,
620 "comms::option::def::VarLength option is not applicable to String field");
621 static_assert(!ParsedOptions::HasAvailableLengthLimit,
622 "comms::option::def::AvailableLengthLimit option is not applicable to String field");
623 static_assert(!ParsedOptions::HasScalingRatio,
624 "comms::option::def::ScalingRatio option is not applicable to String field");
625 static_assert(!ParsedOptions::HasUnits,
626 "comms::option::def::Units option is not applicable to String field");
627 static_assert(!ParsedOptions::HasMultiRangeValidation,
628 "comms::option::def::ValidNumValueRange (or similar) option is not applicable to String field");
629 static_assert(!ParsedOptions::HasSequenceElemSerLengthFieldPrefix,
630 "comms::option::def::SequenceElemSerLengthFieldPrefix option is not applicable to String field");
631 static_assert(!ParsedOptions::HasSequenceElemFixedSerLengthFieldPrefix,
632 "comms::option::def::SequenceElemSerLengthFixedFieldPrefix option is not applicable to String field");
633 static_assert(!ParsedOptions::HasVersionsRange,
634 "comms::option::def::ExistsBetweenVersions (or similar) option is not applicable to String field");
635 static_assert(!ParsedOptions::HasMissingOnReadFail,
636 "comms::option::def::MissingOnReadFail option is not applicable to String field");
637 static_assert(!ParsedOptions::HasMissingOnInvalid,
638 "comms::option::def::MissingOnInvalid option is not applicable to String field");
639};
640
646template <typename TFieldBase, typename... TOptions>
649 const String<TFieldBase, TOptions...>& field2) noexcept
650{
651 return field1.value() == field2.value();
652}
653
659template <typename TFieldBase, typename... TOptions>
662 const String<TFieldBase, TOptions...>& field2) noexcept
663{
664 return field1.value() != field2.value();
665}
666
673template <typename TFieldBase, typename... TOptions>
676 const String<TFieldBase, TOptions...>& field2) noexcept
677{
678 return field1.value() < field2.value();
679}
680
686template <typename T>
687constexpr bool isString()
688{
689 return std::is_same<typename T::CommsTag, tag::String>::value;
690}
691
695template <typename TFieldBase, typename... TOptions>
696inline
697String<TFieldBase, TOptions...>&
699{
700 return field;
701}
702
706template <typename TFieldBase, typename... TOptions>
707inline
708const String<TFieldBase, TOptions...>&
710{
711 return field;
712}
713
714} // namespace field
715
716} // namespace comms
717
718
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:161
TFieldBase FieldBase
Base class provided in the first template parameter.
Definition String.h:165
typename ParsedOptions::SequenceTrailingFieldSuffix TrailingFieldSuffix
Type of trailing field suffix specified via comms::option::def::SequenceTrailingFieldSuffix.
Definition String.h:205
static constexpr bool hasFailOnInvalid()
Compile time inquiry of whether comms::option::def::FailOnInvalid option has been used.
Definition String.h:245
String(const ValueType &val)
Constructor.
Definition String.h:211
constexpr bool isString()
Compile time check function of whether a provided type is any variant of comms::field::String.
Definition String.h:687
typename ParsedOptions::FieldType FieldType
Type of actual extending field specified via comms::option::def::FieldType.
Definition String.h:189
static constexpr bool hasTerminationFieldSuffix()
Compile time inquiry of whether comms::option::def::SequenceTerminationFieldSuffix option has been us...
Definition String.h:287
static constexpr bool hasWriteNoStatus()
Compile time check of whether the field has proper writeNoStatus() member function.
Definition String.h:453
static constexpr bool hasFieldType()
Compile time inquiry of whether comms::option::def::FieldType option has been used.
Definition String.h:266
typename ParsedOptions::SequenceTerminationFieldSuffix TerminationFieldSuffix
Type of termination field suffix specified via comms::option::def::SequenceTerminationFieldSuffix.
Definition String.h:201
static constexpr std::size_t fixedSize()
Compile time inquiry of fixed size provided via comms::option::def::SequenceFixedSize option.
Definition String.h:323
typename ParsedOptions::SequenceSerLengthFieldPrefix SerLengthFieldPrefix
Type of length field prefix specified via comms::option::def::SequenceSerLengthFieldPrefix.
Definition String.h:197
static constexpr std::size_t minLength()
Get minimal length that is required to serialise field of this type.
Definition String.h:470
ErrorStatus read(TIter &iter, std::size_t len)
Read field value from input data sequence.
Definition String.h:339
static constexpr bool hasSerLengthFieldPrefix()
Compile time inquiry of whether comms::option::def::SequenceSerLengthFieldPrefix option has been used...
Definition String.h:280
~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:486
void setValue(U &&val)
Set value.
Definition String.h:403
bool operator!=(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Non-equality comparison operator.
Definition String.h:660
bool canWrite() const
Check of whether the field has a consistent value for writing.
Definition String.h:428
static constexpr bool hasSizeFieldPrefix()
Compile time inquiry of whether comms::option::def::SequenceSizeFieldPrefix option has been used.
Definition String.h:273
VersionType getVersion() const
Get version of the field.
Definition String.h:532
void forceReadLength(std::size_t count)
Force available length for the next read() invocation.
Definition String.h:504
static constexpr bool hasFixedValue()
Compile time inquiry of whether comms::option::def::FixedValue option has been used.
Definition String.h:308
bool setVersion(VersionType version)
Default implementation of version update.
Definition String.h:539
ErrorStatus write(TIter &iter, std::size_t len) const
Write current field value to output data sequence.
Definition String.h:446
static constexpr bool hasIgnoreInvalid()
Compile time inquiry of whether comms::option::def::IgnoreInvalid option has been used.
Definition String.h:252
void clearReadElemCount()
Clear forcing of the number of characters that must be read in the next read() invocation.
Definition String.h:495
const ValueType & getValue() const
Get value.
Definition String.h:395
bool operator<(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition String.h:674
typename BaseImpl::CommsTag CommsTag
Tag indicating type of the field.
Definition String.h:177
static constexpr bool hasReadNoStatus()
Compile time check of whether the field has proper readNoStatus() member function.
Definition String.h:356
typename BaseImpl::ValueType ValueType
Type of underlying value.
Definition String.h:184
bool valid() const
Check validity of the field value.
Definition String.h:415
static constexpr bool hasFixedSize()
Compile time inquiry of whether comms::option::def::SequenceFixedSize option has been used.
Definition String.h:301
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:698
bool refresh()
Refresh the field's value.
Definition String.h:422
String(const char *str)
Constructor.
Definition String.h:223
String()=default
Default constructor.
typename BaseImpl::VersionType VersionType
Version type.
Definition String.h:171
String(String &&)=default
Move constructor.
std::size_t length() const
Get length of serialised data.
Definition String.h:409
details::OptionsParser< TOptions... > ParsedOptions
All the options provided to this class bundled into struct.
Definition String.h:174
static constexpr bool hasEmptySerialization()
Compile time inquiry of whether comms::option::def::EmptySerialization option has been used.
Definition String.h:259
typename BaseImpl::Endian Endian
Endian used for serialisation.
Definition String.h:168
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:709
static constexpr bool hasNonDefaultRefresh()
Compile time check if this class has non-default refresh functionality.
Definition String.h:525
String(ValueType &&val)
Constructor.
Definition String.h:217
typename ParsedOptions::SequenceSizeFieldPrefix SizeFieldPrefix
Type of size field prefix specified via comms::option::def::SequenceSizeFieldPrefix.
Definition String.h:193
void clearReadLengthForcing()
Clear forcing of the available length in the next read() invocation.
Definition String.h:513
ValueType & value()
Get access to the value storage.
Definition String.h:382
static constexpr bool hasTrailingFieldSuffix()
Compile time inquiry of whether comms::option::def::SequenceTrailingFieldSuffix option has been used.
Definition String.h:294
const ValueType & value() const
Get access to the value storage.
Definition String.h:388
void writeNoStatus(TIter &iter) const
Write current field value to output data sequence without error check and status report.
Definition String.h:464
static constexpr std::size_t maxLength()
Get maximal length that is required to serialise field of this type.
Definition String.h:476
void readNoStatus(TIter &iter)
Read field value from input data sequence without error check and status report.
Definition String.h:367
bool operator==(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Equality comparison operator.
Definition String.h:647
static constexpr bool isVersionDependent()
Compile time check if this class is version dependent.
Definition String.h:519
static constexpr bool hasName()
Compile time inquiry of whether comms::option::def::HasName option has been used.
Definition String.h:315
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:28
Replacement to some types from standard type_traits.
Various compile-time detection functions of whether specific member functions and/or types exist.