COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
AssignHelper.h
Go to the documentation of this file.
1//
2// Copyright 2020 - 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 <type_traits>
14#include <iterator>
15
16#include "comms/util/detect.h"
18#include "comms/Assert.h"
19#include "comms/details/tag.h"
20
21namespace comms
22{
23
24namespace util
25{
26
27namespace details
28{
29
30template <typename...>
31class AssignHelper
32{
33public:
34 template <typename T, typename TIter>
35 static void assign(T& obj, TIter from, TIter to)
36 {
37 using ObjType = typename std::decay<decltype(obj)>::type;
38 static_assert(!std::is_same<Tag<ObjType>, UnknownTag<> >::value, "Assignment to provided type is not supported");
39 assignInternal(obj, from, to, Tag<ObjType>());
40 }
41
42private:
43 template <typename... TParams>
44 using UseAssignTag = comms::details::tag::Tag1<>;
45
46 template <typename... TParams>
47 using UsePtrSizeConstructorTag = comms::details::tag::Tag2<>;
48
49 template <typename... TParams>
50 using StdSpanTag = comms::details::tag::Tag3<>;
51
52 template <typename... TParams>
53 using UnknownTag = comms::details::tag::Tag4<>;
54
55 template <typename T>
56 using ConstructorTag =
57 typename comms::util::LazyShallowConditional<
58 comms::util::detect::hasPtrSizeConstructor<T>()
59 >::template Type<
60 UsePtrSizeConstructorTag,
61 UnknownTag
62 >;
63
64 template <typename T>
65 using SpanConstructorTag =
66 typename comms::util::LazyShallowConditional<
67 comms::util::detect::details::IsStdSpan<T>::Value
68 >::template Type<
69 StdSpanTag,
70 ConstructorTag,
71 T
72 >;
73
74 template <typename T>
75 using Tag =
76 typename comms::util::LazyShallowConditional<
77 comms::util::detect::hasAssignFunc<T>()
78 >::template Type<
79 UseAssignTag,
80 SpanConstructorTag,
81 T
82 >;
83
84 template <typename T, typename TIter, typename... TParams>
85 static void assignInternal(T& obj, TIter from, TIter to, UseAssignTag<TParams...>)
86 {
87 obj.assign(from, to);
88 }
89
90 template <typename T, typename TIter, typename... TParams>
91 static void assignInternal(T& obj, TIter from, TIter to, UsePtrSizeConstructorTag<TParams...>)
92 {
93 using IterType = typename std::decay<TIter>::type;
94 using IterTag = typename std::iterator_traits<IterType>::iterator_category;
95 static_assert(std::is_base_of<std::random_access_iterator_tag, IterTag>::value,
96 "Only random access iterator is supported for provided type assignments");
97
98 auto diff = std::distance(from, to);
99 if (diff < 0) {
100 static constexpr bool Invalid_iterators_used_for_assignment = false;
101 static_cast<void>(Invalid_iterators_used_for_assignment);
102 COMMS_ASSERT(Invalid_iterators_used_for_assignment);
103 return;
104 }
105
106 using ObjType = typename std::decay<decltype(obj)>::type;
107 obj = ObjType(&(*from), static_cast<std::size_t>(diff));
108 }
109
110 template <typename T, typename TIter, typename... TParams>
111 static void assignInternal(T& obj, TIter from, TIter to, StdSpanTag<TParams...>)
112 {
113 using ObjType = typename std::decay<decltype(obj)>::type;
114 using ConstPointerType = typename ObjType::const_pointer;
115 using PointerType = typename ObjType::pointer;
116 auto fromPtr = const_cast<PointerType>(reinterpret_cast<ConstPointerType>(&(*from)));
117 auto toPtr = const_cast<PointerType>(reinterpret_cast<ConstPointerType>(&(*to)));
118 assignInternal(obj, fromPtr, toPtr, UsePtrSizeConstructorTag<TParams...>());
119 }
120};
121
122} // namespace details
123
124} // namespace util
125
126} // namespace comms
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
void assign(T &obj, TIter from, TIter to)
Assigns a new value to provided object.
Definition assign.h:39
Main namespace for all classes / functions of COMMS library.
Replacement to some types from standard type_traits.
Various compile-time detection functions of whether specific member functions and/or types exist.