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 - 2024 (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
157template <typename TFieldBase, typename... TOptions>
158class String : public details::StringBase<TFieldBase, TOptions...>
159{
160 using BaseImpl = details::StringBase<TFieldBase, TOptions...>;
161public:
163 using FieldBase = TFieldBase;
164
166 using Endian = typename BaseImpl::Endian;
167
169 using VersionType = typename BaseImpl::VersionType;
170
172 using ParsedOptions = details::OptionsParser<TOptions...>;
173
175 using CommsTag = typename BaseImpl::CommsTag;
176
182 using ValueType = typename BaseImpl::ValueType;
183
187 using FieldType = typename ParsedOptions::FieldType;
188
191 using SizeFieldPrefix = typename ParsedOptions::SequenceSizeFieldPrefix;
192
195 using SerLengthFieldPrefix = typename ParsedOptions::SequenceSerLengthFieldPrefix;
196
199 using TerminationFieldSuffix = typename ParsedOptions::SequenceTerminationFieldSuffix;
200
203 using TrailingFieldSuffix = typename ParsedOptions::SequenceTrailingFieldSuffix;
204
206 String() = default;
207
209 explicit String(const ValueType& val)
210 : BaseImpl(val)
211 {
212 }
213
215 explicit String(ValueType&& val)
216 : BaseImpl(std::move(val))
217 {
218 }
219
221 explicit String(const char* str)
222 {
223 setValue(str);
224 }
225
227 String(const String&) = default;
228
230 String(String&&) = default;
231
233 ~String() noexcept = default;
234
236 String& operator=(const String&) = default;
237
239 String& operator=(String&&) = default;
240
243 static constexpr bool hasFailOnInvalid()
244 {
245 return ParsedOptions::HasFailOnInvalid;
246 }
247
250 static constexpr bool hasIgnoreInvalid()
251 {
252 return ParsedOptions::HasIgnoreInvalid;
253 }
254
257 static constexpr bool hasEmptySerialization()
258 {
259 return ParsedOptions::HasEmptySerialization;
260 }
261
264 static constexpr bool hasFieldType()
265 {
266 return ParsedOptions::HasFieldType;
267 }
268
271 static constexpr bool hasSizeFieldPrefix()
272 {
273 return ParsedOptions::HasSequenceSizeFieldPrefix;
274 }
275
278 static constexpr bool hasSerLengthFieldPrefix()
279 {
280 return ParsedOptions::HasSequenceSerLengthFieldPrefix;
281 }
282
285 static constexpr bool hasTerminationFieldSuffix()
286 {
287 return ParsedOptions::HasSequenceTerminationFieldSuffix;
288 }
289
292 static constexpr bool hasTrailingFieldSuffix()
293 {
294 return ParsedOptions::HasSequenceTrailingFieldSuffix;
295 }
296
299 static constexpr bool hasFixedSize()
300 {
301 return ParsedOptions::HasSequenceFixedSize;
302 }
303
307 static constexpr std::size_t fixedSize()
308 {
309 return ParsedOptions::SequenceFixedSize;
310 }
311
322 template <typename TIter>
323 ErrorStatus read(TIter& iter, std::size_t len)
324 {
325 auto es = BaseImpl::read(iter, len);
326 using TagTmp =
327 typename comms::util::LazyShallowConditional<
328 ParsedOptions::HasSequenceFixedSize
329 >::template Type<
330 AdjustmentNeededTag,
331 NoAdjustmentTag
332 >;
333
334 adjustValue(TagTmp());
335 return es;
336 }
337
340 static constexpr bool hasReadNoStatus()
341 {
342 return BaseImpl::hasReadNoStatus();
343 }
344
350 template <typename TIter>
351 void readNoStatus(TIter& iter)
352 {
353 BaseImpl::readNoStatus(iter);
354 using TagTmp =
355 typename comms::util::LazyShallowConditional<
356 ParsedOptions::HasSequenceFixedSize
357 >::template Type<
358 AdjustmentNeededTag,
359 NoAdjustmentTag
360 >;
361
362 adjustValue(TagTmp());
363 }
364
367 {
368 return BaseImpl::value();
369 }
370
372 const ValueType& value() const
373 {
374 return BaseImpl::value();
375 }
376
379 const ValueType& getValue() const
380 {
381 return BaseImpl::getValue();
382 }
383
386 template <typename U>
387 void setValue(U&& val)
388 {
389 BaseImpl::setValue(std::forward<U>(val));
390 }
391
393 std::size_t length() const
394 {
395 return BaseImpl::length();
396 }
397
399 bool valid() const
400 {
401 return BaseImpl::valid();
402 }
403
406 bool refresh()
407 {
408 return BaseImpl::refresh();
409 }
410
412 bool canWrite() const
413 {
414 return BaseImpl::canWrite();
415 }
416
429 template <typename TIter>
430 ErrorStatus write(TIter& iter, std::size_t len) const
431 {
432 return BaseImpl::write(iter, len);
433 }
434
437 static constexpr bool hasWriteNoStatus()
438 {
439 return BaseImpl::hasWriteNoStatus();
440 }
441
447 template <typename TIter>
448 void writeNoStatus(TIter& iter) const
449 {
450 BaseImpl::writeNoStatus(iter);
451 }
452
454 static constexpr std::size_t minLength()
455 {
456 return BaseImpl::minLength();
457 }
458
460 static constexpr std::size_t maxLength()
461 {
462 return BaseImpl::maxLength();
463 }
464
470 void forceReadElemCount(std::size_t count)
471 {
472 BaseImpl::forceReadElemCount(count);
473 }
474
480 {
481 BaseImpl::clearReadElemCount();
482 }
483
488 void forceReadLength(std::size_t count)
489 {
490 return BaseImpl::forceReadLength(count);
491 }
492
498 {
499 return BaseImpl::clearReadLengthForcing();
500 }
501
503 static constexpr bool isVersionDependent()
504 {
505 return ParsedOptions::HasCustomVersionUpdate || BaseImpl::isVersionDependent();
506 }
507
509 static constexpr bool hasNonDefaultRefresh()
510 {
511 return BaseImpl::hasNonDefaultRefresh();
512 }
513
517 {
518 return BaseImpl::getVersion();
519 }
520
524 {
525 return BaseImpl::setVersion(version);
526 }
527
528protected:
529 using BaseImpl::readData;
530 using BaseImpl::writeData;
531
532private:
533 template <typename... TParams>
534 using NoAdjustmentTag = comms::details::tag::Tag1<>;
535
536 template <typename... TParams>
537 using AdjustmentNeededTag = comms::details::tag::Tag2<>;
538
539 template <typename... TParams>
540 using HasResizeTag = comms::details::tag::Tag3<>;
541
542 template <typename... TParams>
543 using HasRemoveSuffixTag = comms::details::tag::Tag4<>;
544
545 template <typename... TParams>
546 void adjustValue(NoAdjustmentTag<TParams...>)
547 {
548 }
549
550 template <typename... TParams>
551 void adjustValue(AdjustmentNeededTag<TParams...>)
552 {
553 std::size_t count = 0;
554 for (auto iter = BaseImpl::value().begin(); iter != BaseImpl::value().end(); ++iter) {
555 if (*iter == 0) {
556 break;
557 }
558 ++count;
559 }
560
561 doResize(count);
562 }
563
564 void doResize(std::size_t count)
565 {
566 using TagTmp =
568 comms::util::detect::hasResizeFunc<ValueType>()
569 >::template Type<
570 HasResizeTag<>,
572 comms::util::detect::hasRemoveSuffixFunc<ValueType>()
573 >::template Type<
574 HasRemoveSuffixTag<>,
575 void
576 >
577 >;
578
579 static_assert(!std::is_void<TagTmp>::value,
580 "The string storage value type must have either resize() or remove_suffix() "
581 "member functions");
582 doResize(count, TagTmp());
583 }
584
585 template <typename... TParams>
586 void doResize(std::size_t count, HasResizeTag<TParams...>)
587 {
588 BaseImpl::value().resize(count);
589 }
590
591 template <typename... TParams>
592 void doResize(std::size_t count, HasRemoveSuffixTag<TParams...>)
593 {
594 BaseImpl::value().remove_suffix(BaseImpl::value().size() - count);
595 }
596
597 static_assert(!ParsedOptions::HasSerOffset,
598 "comms::option::def::NumValueSerOffset option is not applicable to String field");
599 static_assert(!ParsedOptions::HasFixedLengthLimit,
600 "comms::option::def::FixedLength option is not applicable to String field");
601 static_assert(!ParsedOptions::HasFixedBitLengthLimit,
602 "comms::option::def::FixedBitLength option is not applicable to String field");
603 static_assert(!ParsedOptions::HasVarLengthLimits,
604 "comms::option::def::VarLength option is not applicable to String field");
605 static_assert(!ParsedOptions::HasAvailableLengthLimit,
606 "comms::option::def::AvailableLengthLimit option is not applicable to String field");
607 static_assert(!ParsedOptions::HasScalingRatio,
608 "comms::option::def::ScalingRatio option is not applicable to String field");
609 static_assert(!ParsedOptions::HasUnits,
610 "comms::option::def::Units option is not applicable to String field");
611 static_assert(!ParsedOptions::HasMultiRangeValidation,
612 "comms::option::def::ValidNumValueRange (or similar) option is not applicable to String field");
613 static_assert(!ParsedOptions::HasSequenceElemSerLengthFieldPrefix,
614 "comms::option::def::SequenceElemSerLengthFieldPrefix option is not applicable to String field");
615 static_assert(!ParsedOptions::HasSequenceElemFixedSerLengthFieldPrefix,
616 "comms::option::def::SequenceElemSerLengthFixedFieldPrefix option is not applicable to String field");
617 static_assert(!ParsedOptions::HasVersionsRange,
618 "comms::option::def::ExistsBetweenVersions (or similar) option is not applicable to String field");
619 static_assert(!ParsedOptions::HasMissingOnReadFail,
620 "comms::option::def::MissingOnReadFail option is not applicable to String field");
621 static_assert(!ParsedOptions::HasMissingOnInvalid,
622 "comms::option::def::MissingOnInvalid option is not applicable to String field");
623};
624
630template <typename TFieldBase, typename... TOptions>
633 const String<TFieldBase, TOptions...>& field2) noexcept
634{
635 return field1.value() == field2.value();
636}
637
643template <typename TFieldBase, typename... TOptions>
646 const String<TFieldBase, TOptions...>& field2) noexcept
647{
648 return field1.value() != field2.value();
649}
650
657template <typename TFieldBase, typename... TOptions>
660 const String<TFieldBase, TOptions...>& field2) noexcept
661{
662 return field1.value() < field2.value();
663}
664
670template <typename T>
671constexpr bool isString()
672{
673 return std::is_same<typename T::CommsTag, tag::String>::value;
674}
675
679template <typename TFieldBase, typename... TOptions>
680inline
681String<TFieldBase, TOptions...>&
683{
684 return field;
685}
686
690template <typename TFieldBase, typename... TOptions>
691inline
692const String<TFieldBase, TOptions...>&
694{
695 return field;
696}
697
698} // namespace field
699
700} // namespace comms
701
702
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:159
TFieldBase FieldBase
Base class provided in the first template parameter.
Definition String.h:163
typename ParsedOptions::SequenceTrailingFieldSuffix TrailingFieldSuffix
Type of trailing field suffix specified via comms::option::def::SequenceTrailingFieldSuffix.
Definition String.h:203
static constexpr bool hasFailOnInvalid()
Compile time inquiry of whether comms::option::def::FailOnInvalid option has been used.
Definition String.h:243
String(const ValueType &val)
Constructor.
Definition String.h:209
constexpr bool isString()
Compile time check function of whether a provided type is any variant of comms::field::String.
Definition String.h:671
typename ParsedOptions::FieldType FieldType
Type of actual extending field specified via comms::option::def::FieldType.
Definition String.h:187
static constexpr bool hasTerminationFieldSuffix()
Compile time inquiry of whether comms::option::def::SequenceTerminationFieldSuffix option has been us...
Definition String.h:285
static constexpr bool hasWriteNoStatus()
Compile time check of whether the field has proper writeNoStatus() member function.
Definition String.h:437
static constexpr bool hasFieldType()
Compile time inquiry of whether comms::option::def::FieldType option has been used.
Definition String.h:264
typename ParsedOptions::SequenceTerminationFieldSuffix TerminationFieldSuffix
Type of termination field suffix specified via comms::option::def::SequenceTerminationFieldSuffix.
Definition String.h:199
static constexpr std::size_t fixedSize()
Compile time inquiry of fixed size provided via comms::option::def::SequenceFixedSize option.
Definition String.h:307
typename ParsedOptions::SequenceSerLengthFieldPrefix SerLengthFieldPrefix
Type of length field prefix specified via comms::option::def::SequenceSerLengthFieldPrefix.
Definition String.h:195
static constexpr std::size_t minLength()
Get minimal length that is required to serialise field of this type.
Definition String.h:454
ErrorStatus read(TIter &iter, std::size_t len)
Read field value from input data sequence.
Definition String.h:323
static constexpr bool hasSerLengthFieldPrefix()
Compile time inquiry of whether comms::option::def::SequenceSerLengthFieldPrefix option has been used...
Definition String.h:278
~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:470
void setValue(U &&val)
Set value.
Definition String.h:387
bool operator!=(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Non-equality comparison operator.
Definition String.h:644
bool canWrite() const
Check of whether the field has a consistent value for writing.
Definition String.h:412
static constexpr bool hasSizeFieldPrefix()
Compile time inquiry of whether comms::option::def::SequenceSizeFieldPrefix option has been used.
Definition String.h:271
VersionType getVersion() const
Get version of the field.
Definition String.h:516
void forceReadLength(std::size_t count)
Force available length for the next read() invocation.
Definition String.h:488
bool setVersion(VersionType version)
Default implementation of version update.
Definition String.h:523
ErrorStatus write(TIter &iter, std::size_t len) const
Write current field value to output data sequence.
Definition String.h:430
static constexpr bool hasIgnoreInvalid()
Compile time inquiry of whether comms::option::def::IgnoreInvalid option has been used.
Definition String.h:250
void clearReadElemCount()
Clear forcing of the number of characters that must be read in the next read() invocation.
Definition String.h:479
const ValueType & getValue() const
Get value.
Definition String.h:379
bool operator<(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition String.h:658
typename BaseImpl::CommsTag CommsTag
Tag indicating type of the field.
Definition String.h:175
static constexpr bool hasReadNoStatus()
Compile time check of whether the field has proper readNoStatus() member function.
Definition String.h:340
typename BaseImpl::ValueType ValueType
Type of underlying value.
Definition String.h:182
bool valid() const
Check validity of the field value.
Definition String.h:399
static constexpr bool hasFixedSize()
Compile time inquiry of whether comms::option::def::SequenceFixedSize option has been used.
Definition String.h:299
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:682
bool refresh()
Refresh the field's value.
Definition String.h:406
String(const char *str)
Constructor.
Definition String.h:221
String()=default
Default constructor.
typename BaseImpl::VersionType VersionType
Version type.
Definition String.h:169
String(String &&)=default
Move constructor.
std::size_t length() const
Get length of serialised data.
Definition String.h:393
details::OptionsParser< TOptions... > ParsedOptions
All the options provided to this class bundled into struct.
Definition String.h:172
static constexpr bool hasEmptySerialization()
Compile time inquiry of whether comms::option::def::EmptySerialization option has been used.
Definition String.h:257
typename BaseImpl::Endian Endian
Endian used for serialisation.
Definition String.h:166
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:693
static constexpr bool hasNonDefaultRefresh()
Compile time check if this class has non-default refresh functionality.
Definition String.h:509
String(ValueType &&val)
Constructor.
Definition String.h:215
typename ParsedOptions::SequenceSizeFieldPrefix SizeFieldPrefix
Type of size field prefix specified via comms::option::def::SequenceSizeFieldPrefix.
Definition String.h:191
void clearReadLengthForcing()
Clear forcing of the available length in the next read() invocation.
Definition String.h:497
ValueType & value()
Get access to the value storage.
Definition String.h:366
static constexpr bool hasTrailingFieldSuffix()
Compile time inquiry of whether comms::option::def::SequenceTrailingFieldSuffix option has been used.
Definition String.h:292
const ValueType & value() const
Get access to the value storage.
Definition String.h:372
void writeNoStatus(TIter &iter) const
Write current field value to output data sequence without error check and status report.
Definition String.h:448
static constexpr std::size_t maxLength()
Get maximal length that is required to serialise field of this type.
Definition String.h:460
void readNoStatus(TIter &iter)
Read field value from input data sequence without error check and status report.
Definition String.h:351
bool operator==(const String< TFieldBase, TOptions... > &field1, const String< TFieldBase, TOptions... > &field2) noexcept
Equality comparison operator.
Definition String.h:631
static constexpr bool isVersionDependent()
Compile time check if this class is version dependent.
Definition String.h:503
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.