Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Utilities/cmcppdap/include/dap/any.h
Line
Count
Source
1
// Copyright 2019 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#ifndef dap_any_h
16
#define dap_any_h
17
18
#include "typeinfo.h"
19
20
#include <assert.h>
21
#include <stdint.h>
22
23
namespace dap {
24
25
template <typename T>
26
struct TypeOf;
27
class Deserializer;
28
class Serializer;
29
30
// any provides a type-safe container for values of any of dap type (boolean,
31
// integer, number, array, variant, any, null, dap-structs).
32
class any {
33
 public:
34
  // constructors
35
0
  inline any() = default;
36
  inline any(const any& other) noexcept;
37
  inline any(any&& other) noexcept;
38
39
  template <typename T>
40
  inline any(const T& val);
41
42
  // destructors
43
  inline ~any();
44
45
  // replaces the contained value with a null.
46
  inline void reset();
47
48
  // assignment
49
  inline any& operator=(const any& rhs);
50
  inline any& operator=(any&& rhs) noexcept;
51
  template <typename T>
52
  inline any& operator=(const T& val);
53
  inline any& operator=(const std::nullptr_t& val);
54
55
  // get() returns the contained value of the type T.
56
  // If the any does not contain a value of type T, then get() will assert.
57
  template <typename T>
58
  inline T& get() const;
59
60
  // is() returns true iff the contained value is of type T.
61
  template <typename T>
62
  inline bool is() const;
63
64
 private:
65
  friend class Deserializer;
66
  friend class Serializer;
67
68
  static inline void* alignUp(void* val, size_t alignment);
69
  inline void alloc(size_t size, size_t align);
70
  inline void free();
71
  inline bool isInBuffer(void* ptr) const;
72
73
  void* value = nullptr;
74
  const TypeInfo* type = nullptr;
75
  void* heap = nullptr;  // heap allocation
76
  uint8_t buffer[32];    // or internal allocation
77
};
78
79
0
inline any::~any() {
80
0
  reset();
81
0
}
82
83
template <typename T>
84
0
inline any::any(const T& val) {
85
0
  *this = val;
86
0
}
Unexecuted instantiation: dap::any::any<std::__1::vector<dap::any, std::__1::allocator<dap::any> > >(std::__1::vector<dap::any, std::__1::allocator<dap::any> > const&)
Unexecuted instantiation: dap::any::any<dap::integer>(dap::integer const&)
Unexecuted instantiation: dap::any::any<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
87
88
0
any::any(const any& other) noexcept : type(other.type) {
89
0
  if (other.value != nullptr) {
90
0
    alloc(type->size(), type->alignment());
91
0
    type->copyConstruct(value, other.value);
92
0
  }
93
0
}
94
95
0
any::any(any&& other) noexcept : type(other.type) {
96
0
  if (other.isInBuffer(other.value)) {
97
0
    alloc(type->size(), type->alignment());
98
0
    type->copyConstruct(value, other.value);
99
0
  } else {
100
0
    value = other.value;
101
0
  }
102
0
  other.value = nullptr;
103
0
  other.type = nullptr;
104
0
}
105
106
0
void any::reset() {
107
0
  if (value != nullptr) {
108
0
    type->destruct(value);
109
0
    free();
110
0
  }
111
0
  value = nullptr;
112
0
  type = nullptr;
113
0
}
114
115
0
any& any::operator=(const any& rhs) {
116
0
  reset();
117
0
  type = rhs.type;
118
0
  if (rhs.value != nullptr) {
119
0
    alloc(type->size(), type->alignment());
120
0
    type->copyConstruct(value, rhs.value);
121
0
  }
122
0
  return *this;
123
0
}
124
125
0
any& any::operator=(any&& rhs) noexcept {
126
0
  reset();
127
0
  type = rhs.type;
128
0
  if (rhs.isInBuffer(rhs.value)) {
129
0
    alloc(type->size(), type->alignment());
130
0
    type->copyConstruct(value, rhs.value);
131
0
  } else {
132
0
    value = rhs.value;
133
0
  }
134
0
  rhs.value = nullptr;
135
0
  rhs.type = nullptr;
136
0
  return *this;
137
0
}
138
139
template <typename T>
140
0
any& any::operator=(const T& val) {
141
0
  if (!is<T>()) {
142
0
    reset();
143
0
    type = TypeOf<T>::type();
144
0
    alloc(type->size(), type->alignment());
145
0
    type->copyConstruct(value, &val);
146
0
  } else {
147
#ifdef __clang_analyzer__
148
    assert(value != nullptr);
149
#endif
150
0
    *reinterpret_cast<T*>(value) = val;
151
0
  }
152
0
  return *this;
153
0
}
Unexecuted instantiation: dap::any& dap::any::operator=<std::__1::vector<dap::any, std::__1::allocator<dap::any> > >(std::__1::vector<dap::any, std::__1::allocator<dap::any> > const&)
Unexecuted instantiation: dap::any& dap::any::operator=<dap::integer>(dap::integer const&)
Unexecuted instantiation: dap::any& dap::any::operator=<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: dap::any& dap::any::operator=<dap::boolean>(dap::boolean const&)
Unexecuted instantiation: dap::any& dap::any::operator=<dap::number>(dap::number const&)
Unexecuted instantiation: dap::any& dap::any::operator=<std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, dap::any, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, dap::any> > > >(std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, dap::any, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, dap::any> > > const&)
154
155
0
any& any::operator=(const std::nullptr_t&) {
156
0
  reset();
157
0
  return *this;
158
0
}
159
160
template <typename T>
161
0
T& any::get() const {
162
0
  static_assert(!std::is_same<T, std::nullptr_t>::value,
163
0
                "Cannot get nullptr from 'any'.");
164
0
  assert(is<T>());
165
0
  return *reinterpret_cast<T*>(value);
166
0
}
Unexecuted instantiation: dap::boolean& dap::any::get<dap::boolean>() const
Unexecuted instantiation: dap::integer& dap::any::get<dap::integer>() const
Unexecuted instantiation: dap::number& dap::any::get<dap::number>() const
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >& dap::any::get<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Unexecuted instantiation: std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, dap::any, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, dap::any> > >& dap::any::get<std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, dap::any, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, dap::any> > > >() const
167
168
template <typename T>
169
0
bool any::is() const {
170
0
  return type == TypeOf<T>::type();
171
0
}
Unexecuted instantiation: bool dap::any::is<std::__1::vector<dap::any, std::__1::allocator<dap::any> > >() const
Unexecuted instantiation: bool dap::any::is<dap::integer>() const
Unexecuted instantiation: bool dap::any::is<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Unexecuted instantiation: bool dap::any::is<dap::boolean>() const
Unexecuted instantiation: bool dap::any::is<dap::number>() const
Unexecuted instantiation: bool dap::any::is<std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, dap::any, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, dap::any> > > >() const
172
173
template <>
174
0
inline bool any::is<std::nullptr_t>() const {
175
0
  return value == nullptr;
176
0
}
177
178
0
void* any::alignUp(void* val, size_t alignment) {
179
0
  auto ptr = reinterpret_cast<uintptr_t>(val);
180
0
  return reinterpret_cast<void*>(alignment *
181
0
                                 ((ptr + alignment - 1) / alignment));
182
0
}
183
184
0
void any::alloc(size_t size, size_t align) {
185
0
  assert(value == nullptr);
186
0
  value = alignUp(buffer, align);
187
0
  if (isInBuffer(reinterpret_cast<uint8_t*>(value) + size - 1)) {
188
0
    return;
189
0
  }
190
0
  heap = new uint8_t[size + align];
191
0
  value = alignUp(heap, align);
192
0
}
193
194
0
void any::free() {
195
0
  assert(value != nullptr);
196
0
  if (heap != nullptr) {
197
0
    delete[] reinterpret_cast<uint8_t*>(heap);
198
0
    heap = nullptr;
199
0
  }
200
0
  value = nullptr;
201
0
}
202
203
0
bool any::isInBuffer(void* ptr) const {
204
0
  auto addr = reinterpret_cast<uintptr_t>(ptr);
205
0
  return addr >= reinterpret_cast<uintptr_t>(buffer) &&
206
0
         addr < reinterpret_cast<uintptr_t>(buffer + sizeof(buffer));
207
0
}
208
209
}  // namespace dap
210
211
#endif  // dap_any_h