Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmSbomObject.h
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#pragma once
4
5
#include <cstddef>
6
#include <memory>
7
#include <string>
8
#include <vector>
9
10
#include <cm/type_traits>
11
12
#include "cmSbomSerializer.h"
13
14
class cmSbomObject;
15
16
template <typename T>
17
inline void SerializeDispatch(T const& t, cmSbomSerializer& serializer)
18
0
{
19
0
  serializer.BeginObject();
20
0
  t.Serialize(serializer);
21
0
  serializer.EndObject();
22
0
}
Unexecuted instantiation: void SerializeDispatch<cmSpdxDocument>(cmSpdxDocument const&, cmSbomSerializer&)
Unexecuted instantiation: void SerializeDispatch<cmSpdxPackage>(cmSpdxPackage const&, cmSbomSerializer&)
Unexecuted instantiation: void SerializeDispatch<cmSbomDocument>(cmSbomDocument const&, cmSbomSerializer&)
Unexecuted instantiation: void SerializeDispatch<cmSpdxOrganization>(cmSpdxOrganization const&, cmSbomSerializer&)
Unexecuted instantiation: void SerializeDispatch<cmSpdxTool>(cmSpdxTool const&, cmSbomSerializer&)
Unexecuted instantiation: void SerializeDispatch<cmSpdxCreationInfo>(cmSpdxCreationInfo const&, cmSbomSerializer&)
Unexecuted instantiation: void SerializeDispatch<cmSpdxExternalRef>(cmSpdxExternalRef const&, cmSbomSerializer&)
Unexecuted instantiation: void SerializeDispatch<cmSpdxRelationship>(cmSpdxRelationship const&, cmSbomSerializer&)
23
24
template <typename T>
25
inline void SerializeDispatch(T* p, cmSbomSerializer& serializer)
26
0
{
27
0
  if (p->SpdxId) {
28
0
    serializer.AddReference(*p->SpdxId);
29
0
  }
30
0
}
31
32
inline void SerializeDispatch(std::nullptr_t, cmSbomSerializer&)
33
0
{
34
0
}
35
36
struct ObjectInterface
37
{
38
  virtual ObjectInterface* Copy(void* storage) const = 0;
39
  virtual ObjectInterface* Move(void* storage) = 0;
40
  virtual void* Addr() noexcept = 0;
41
  virtual void const* Addr() const noexcept = 0;
42
  virtual void SerializeImpl(cmSbomSerializer& os) const = 0;
43
0
  virtual ~ObjectInterface() = default;
44
45
0
  ObjectInterface() = default;
46
  ObjectInterface(ObjectInterface const&) = default;
47
  ObjectInterface& operator=(ObjectInterface const&) = default;
48
0
  ObjectInterface(ObjectInterface&&) noexcept = default;
49
  ObjectInterface& operator=(ObjectInterface&&) noexcept = default;
50
};
51
52
namespace impl {
53
54
#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20150623
55
using max_align_t = ::max_align_t;
56
#else
57
using max_align_t = std::max_align_t;
58
#endif
59
60
enum class StorageKind
61
{
62
  Stack,
63
  Heap
64
};
65
66
template <typename, StorageKind>
67
struct Storage
68
{
69
};
70
71
template <typename T>
72
struct Storage<T, StorageKind::Stack> : ObjectInterface
73
{
74
  using ValueType = cm::decay_t<T>;
75
76
  explicit Storage(T x)
77
0
    : Value(std::move(x))
78
0
  {
79
0
  }
80
81
  Storage(Storage&&) noexcept(
82
0
    std::is_nothrow_move_constructible<ValueType>::value) = default;
Unexecuted instantiation: impl::Storage<cmSpdxPackage const*, (impl::StorageKind)0>::Storage(impl::Storage<cmSpdxPackage const*, (impl::StorageKind)0>&&)
Unexecuted instantiation: impl::Storage<cmSbomDocument, (impl::StorageKind)0>::Storage(impl::Storage<cmSbomDocument, (impl::StorageKind)0>&&)
83
0
  ~Storage() override = default;
84
85
0
  void* Addr() noexcept override { return std::addressof(Value); }
Unexecuted instantiation: impl::Storage<cmSpdxPackage const*, (impl::StorageKind)0>::Addr()
Unexecuted instantiation: impl::Storage<cmSbomDocument, (impl::StorageKind)0>::Addr()
86
0
  void const* Addr() const noexcept override { return std::addressof(Value); }
Unexecuted instantiation: impl::Storage<cmSpdxPackage const*, (impl::StorageKind)0>::Addr() const
Unexecuted instantiation: impl::Storage<cmSbomDocument, (impl::StorageKind)0>::Addr() const
87
88
  ValueType& get() { return Value; }
89
0
  ValueType const& get() const { return Value; }
Unexecuted instantiation: impl::Storage<cmSpdxPackage const*, (impl::StorageKind)0>::get() const
Unexecuted instantiation: impl::Storage<cmSbomDocument, (impl::StorageKind)0>::get() const
90
91
private:
92
  ValueType Value;
93
};
94
95
template <typename T>
96
struct Storage<T, StorageKind::Heap> : ObjectInterface
97
{
98
  using ValueType = cm::decay_t<T>;
99
100
  explicit Storage(T x)
101
0
    : Ptr(new T(std::move(x)))
102
0
  {
103
0
  }
Unexecuted instantiation: impl::Storage<cmSpdxDocument, (impl::StorageKind)1>::Storage(cmSpdxDocument)
Unexecuted instantiation: impl::Storage<cmSpdxPackage, (impl::StorageKind)1>::Storage(cmSpdxPackage)
Unexecuted instantiation: impl::Storage<cmSpdxOrganization, (impl::StorageKind)1>::Storage(cmSpdxOrganization)
Unexecuted instantiation: impl::Storage<cmSpdxTool, (impl::StorageKind)1>::Storage(cmSpdxTool)
Unexecuted instantiation: impl::Storage<cmSpdxCreationInfo, (impl::StorageKind)1>::Storage(cmSpdxCreationInfo)
Unexecuted instantiation: impl::Storage<cmSpdxExternalRef, (impl::StorageKind)1>::Storage(cmSpdxExternalRef)
Unexecuted instantiation: impl::Storage<cmSpdxRelationship, (impl::StorageKind)1>::Storage(cmSpdxRelationship)
104
105
0
  Storage(Storage&&) noexcept = default;
Unexecuted instantiation: impl::Storage<cmSpdxDocument, (impl::StorageKind)1>::Storage(impl::Storage<cmSpdxDocument, (impl::StorageKind)1>&&)
Unexecuted instantiation: impl::Storage<cmSpdxPackage, (impl::StorageKind)1>::Storage(impl::Storage<cmSpdxPackage, (impl::StorageKind)1>&&)
Unexecuted instantiation: impl::Storage<cmSpdxOrganization, (impl::StorageKind)1>::Storage(impl::Storage<cmSpdxOrganization, (impl::StorageKind)1>&&)
Unexecuted instantiation: impl::Storage<cmSpdxTool, (impl::StorageKind)1>::Storage(impl::Storage<cmSpdxTool, (impl::StorageKind)1>&&)
Unexecuted instantiation: impl::Storage<cmSpdxCreationInfo, (impl::StorageKind)1>::Storage(impl::Storage<cmSpdxCreationInfo, (impl::StorageKind)1>&&)
Unexecuted instantiation: impl::Storage<cmSpdxExternalRef, (impl::StorageKind)1>::Storage(impl::Storage<cmSpdxExternalRef, (impl::StorageKind)1>&&)
Unexecuted instantiation: impl::Storage<cmSpdxRelationship, (impl::StorageKind)1>::Storage(impl::Storage<cmSpdxRelationship, (impl::StorageKind)1>&&)
106
0
  ~Storage() override = default;
Unexecuted instantiation: impl::Storage<cmSpdxDocument, (impl::StorageKind)1>::~Storage()
Unexecuted instantiation: impl::Storage<cmSpdxPackage, (impl::StorageKind)1>::~Storage()
Unexecuted instantiation: impl::Storage<cmSpdxOrganization, (impl::StorageKind)1>::~Storage()
Unexecuted instantiation: impl::Storage<cmSpdxTool, (impl::StorageKind)1>::~Storage()
Unexecuted instantiation: impl::Storage<cmSpdxCreationInfo, (impl::StorageKind)1>::~Storage()
Unexecuted instantiation: impl::Storage<cmSpdxExternalRef, (impl::StorageKind)1>::~Storage()
Unexecuted instantiation: impl::Storage<cmSpdxRelationship, (impl::StorageKind)1>::~Storage()
107
108
0
  void* Addr() noexcept override { return Ptr.get(); }
Unexecuted instantiation: impl::Storage<cmSpdxDocument, (impl::StorageKind)1>::Addr()
Unexecuted instantiation: impl::Storage<cmSpdxPackage, (impl::StorageKind)1>::Addr()
Unexecuted instantiation: impl::Storage<cmSpdxOrganization, (impl::StorageKind)1>::Addr()
Unexecuted instantiation: impl::Storage<cmSpdxTool, (impl::StorageKind)1>::Addr()
Unexecuted instantiation: impl::Storage<cmSpdxCreationInfo, (impl::StorageKind)1>::Addr()
Unexecuted instantiation: impl::Storage<cmSpdxExternalRef, (impl::StorageKind)1>::Addr()
Unexecuted instantiation: impl::Storage<cmSpdxRelationship, (impl::StorageKind)1>::Addr()
109
0
  void const* Addr() const noexcept override { return Ptr.get(); }
Unexecuted instantiation: impl::Storage<cmSpdxDocument, (impl::StorageKind)1>::Addr() const
Unexecuted instantiation: impl::Storage<cmSpdxPackage, (impl::StorageKind)1>::Addr() const
Unexecuted instantiation: impl::Storage<cmSpdxOrganization, (impl::StorageKind)1>::Addr() const
Unexecuted instantiation: impl::Storage<cmSpdxTool, (impl::StorageKind)1>::Addr() const
Unexecuted instantiation: impl::Storage<cmSpdxCreationInfo, (impl::StorageKind)1>::Addr() const
Unexecuted instantiation: impl::Storage<cmSpdxExternalRef, (impl::StorageKind)1>::Addr() const
Unexecuted instantiation: impl::Storage<cmSpdxRelationship, (impl::StorageKind)1>::Addr() const
110
111
  ValueType& get() { return *Ptr; }
112
0
  ValueType const& get() const { return *Ptr; }
Unexecuted instantiation: impl::Storage<cmSpdxDocument, (impl::StorageKind)1>::get() const
Unexecuted instantiation: impl::Storage<cmSpdxPackage, (impl::StorageKind)1>::get() const
Unexecuted instantiation: impl::Storage<cmSpdxOrganization, (impl::StorageKind)1>::get() const
Unexecuted instantiation: impl::Storage<cmSpdxTool, (impl::StorageKind)1>::get() const
Unexecuted instantiation: impl::Storage<cmSpdxCreationInfo, (impl::StorageKind)1>::get() const
Unexecuted instantiation: impl::Storage<cmSpdxExternalRef, (impl::StorageKind)1>::get() const
Unexecuted instantiation: impl::Storage<cmSpdxRelationship, (impl::StorageKind)1>::get() const
113
114
private:
115
  std::unique_ptr<ValueType> Ptr;
116
};
117
118
template <>
119
struct Storage<std::nullptr_t, StorageKind::Stack> : ObjectInterface
120
{
121
0
  explicit Storage(std::nullptr_t) {}
122
123
  Storage(Storage&&) noexcept = default;
124
  ~Storage() override = default;
125
126
0
  void* Addr() noexcept override { return nullptr; }
127
0
  void const* Addr() const noexcept override { return nullptr; }
128
129
0
  void SerializeImpl(cmSbomSerializer&) const override {}
130
131
0
  std::nullptr_t get() { return nullptr; }
132
0
  std::nullptr_t get() const { return nullptr; }
133
};
134
135
}
136
137
struct ObjectStorage
138
{
139
  template <typename T>
140
  using Stack = impl::Storage<T, impl::StorageKind::Stack>;
141
  template <typename T>
142
  using Heap = impl::Storage<T, impl::StorageKind::Heap>;
143
144
  static constexpr std::size_t BufferSize = 128u;
145
146
  static constexpr std::size_t Size = sizeof(Heap<std::nullptr_t>) > BufferSize
147
    ? sizeof(Heap<std::nullptr_t>)
148
    : BufferSize;
149
  static constexpr std::size_t Align = alignof(impl::max_align_t);
150
151
  struct Buffer
152
  {
153
    alignas(Align) unsigned char Data[Size];
154
  };
155
156
  template <typename Concrete>
157
  using Model = cm::conditional_t<sizeof(Stack<Concrete>) <= Size &&
158
                                    alignof(Stack<Concrete>) <= Align,
159
                                  Stack<Concrete>, Heap<Concrete>>;
160
};
161
162
class cmSbomObject
163
{
164
public:
165
  template <typename T>
166
  struct Instance : ObjectStorage::Model<T>
167
  {
168
    using Base = ObjectStorage::Model<T>;
169
    using Base::Base;
170
0
    Instance(Instance&&) noexcept = default;
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxDocument>::Instance(cmSbomObject::Instance<cmSpdxDocument>&&)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxPackage>::Instance(cmSbomObject::Instance<cmSpdxPackage>&&)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxPackage const*>::Instance(cmSbomObject::Instance<cmSpdxPackage const*>&&)
Unexecuted instantiation: cmSbomObject::Instance<cmSbomDocument>::Instance(cmSbomObject::Instance<cmSbomDocument>&&)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxOrganization>::Instance(cmSbomObject::Instance<cmSpdxOrganization>&&)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxTool>::Instance(cmSbomObject::Instance<cmSpdxTool>&&)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxCreationInfo>::Instance(cmSbomObject::Instance<cmSpdxCreationInfo>&&)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxExternalRef>::Instance(cmSbomObject::Instance<cmSpdxExternalRef>&&)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxRelationship>::Instance(cmSbomObject::Instance<cmSpdxRelationship>&&)
171
172
    ObjectInterface* Copy(void* storage) const override
173
0
    {
174
0
      return ::new (storage) Instance(this->get());
175
0
    }
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxDocument>::Copy(void*) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxPackage>::Copy(void*) const
Unexecuted instantiation: cmSbomObject::Instance<decltype(nullptr)>::Copy(void*) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxPackage const*>::Copy(void*) const
Unexecuted instantiation: cmSbomObject::Instance<cmSbomDocument>::Copy(void*) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxOrganization>::Copy(void*) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxTool>::Copy(void*) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxCreationInfo>::Copy(void*) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxExternalRef>::Copy(void*) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxRelationship>::Copy(void*) const
176
177
    ObjectInterface* Move(void* storage) override
178
0
    {
179
0
      return ::new (storage) Instance(std::move(*this));
180
0
    }
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxDocument>::Move(void*)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxPackage>::Move(void*)
Unexecuted instantiation: cmSbomObject::Instance<decltype(nullptr)>::Move(void*)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxPackage const*>::Move(void*)
Unexecuted instantiation: cmSbomObject::Instance<cmSbomDocument>::Move(void*)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxOrganization>::Move(void*)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxTool>::Move(void*)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxCreationInfo>::Move(void*)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxExternalRef>::Move(void*)
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxRelationship>::Move(void*)
181
182
    void SerializeImpl(cmSbomSerializer& os) const override
183
0
    {
184
0
      SerializeDispatch(this->get(), os);
185
0
    }
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxDocument>::SerializeImpl(cmSbomSerializer&) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxPackage>::SerializeImpl(cmSbomSerializer&) const
Unexecuted instantiation: cmSbomObject::Instance<decltype(nullptr)>::SerializeImpl(cmSbomSerializer&) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxPackage const*>::SerializeImpl(cmSbomSerializer&) const
Unexecuted instantiation: cmSbomObject::Instance<cmSbomDocument>::SerializeImpl(cmSbomSerializer&) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxOrganization>::SerializeImpl(cmSbomSerializer&) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxTool>::SerializeImpl(cmSbomSerializer&) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxCreationInfo>::SerializeImpl(cmSbomSerializer&) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxExternalRef>::SerializeImpl(cmSbomSerializer&) const
Unexecuted instantiation: cmSbomObject::Instance<cmSpdxRelationship>::SerializeImpl(cmSbomSerializer&) const
186
  };
187
188
0
  cmSbomObject() { ::new (Storage()) Instance<std::nullptr_t>(nullptr); }
189
  cmSbomObject(std::nullptr_t)
190
    : cmSbomObject()
191
0
  {
192
0
  }
193
194
  template <
195
    typename T, typename Decayed = cm::remove_cv_t<cm::remove_reference_t<T>>,
196
    typename = cm::enable_if_t<!std::is_same<Decayed, cmSbomObject>::value>>
197
  cmSbomObject(T&& x)
198
0
  {
199
0
    ::new (Storage()) Instance<Decayed>(std::forward<T>(x));
200
0
  }
Unexecuted instantiation: cmSbomObject::cmSbomObject<cmSpdxDocument, cmSpdxDocument, void>(cmSpdxDocument&&)
Unexecuted instantiation: cmSbomObject::cmSbomObject<cmSpdxPackage, cmSpdxPackage, void>(cmSpdxPackage&&)
Unexecuted instantiation: cmSbomObject::cmSbomObject<cmSpdxPackage const* const&, cmSpdxPackage const*, void>(cmSpdxPackage const* const&)
Unexecuted instantiation: cmSbomObject::cmSbomObject<cmSpdxPackage const*&, cmSpdxPackage const*, void>(cmSpdxPackage const*&)
Unexecuted instantiation: cmSbomObject::cmSbomObject<cmSbomDocument&, cmSbomDocument, void>(cmSbomDocument&)
Unexecuted instantiation: cmSbomObject::cmSbomObject<cmSpdxOrganization, cmSpdxOrganization, void>(cmSpdxOrganization&&)
Unexecuted instantiation: cmSbomObject::cmSbomObject<cmSpdxTool&, cmSpdxTool, void>(cmSpdxTool&)
Unexecuted instantiation: cmSbomObject::cmSbomObject<cmSpdxCreationInfo&, cmSpdxCreationInfo, void>(cmSpdxCreationInfo&)
Unexecuted instantiation: cmSbomObject::cmSbomObject<cmSpdxExternalRef&, cmSpdxExternalRef, void>(cmSpdxExternalRef&)
Unexecuted instantiation: cmSbomObject::cmSbomObject<cmSpdxRelationship, cmSpdxRelationship, void>(cmSpdxRelationship&&)
201
202
  cmSbomObject(cmSbomObject const& other)
203
0
  {
204
0
    other.Interface().Copy(Storage());
205
0
  }
206
  cmSbomObject(cmSbomObject&& other) noexcept
207
0
  {
208
0
    other.Interface().Move(Storage());
209
0
  }
210
211
0
  ~cmSbomObject() noexcept { Interface().~ObjectInterface(); }
212
213
  cmSbomObject& operator=(cmSbomObject rhs)
214
0
  {
215
0
    Interface().~ObjectInterface();
216
0
    rhs.Interface().Move(Storage());
217
0
    return *this;
218
0
  }
219
220
0
  bool IsNull() const noexcept { return Interface().Addr() == nullptr; }
221
0
  explicit operator bool() const noexcept { return !IsNull(); }
222
223
0
  void Serialize(cmSbomSerializer& os) const { Interface().SerializeImpl(os); }
224
225
  template <typename T>
226
  T& CastUnchecked()
227
0
  {
228
0
    return *static_cast<T*>(Interface().Addr());
229
0
  }
Unexecuted instantiation: cmSpdxDocument& cmSbomObject::CastUnchecked<cmSpdxDocument>()
Unexecuted instantiation: cmSpdxPackage& cmSbomObject::CastUnchecked<cmSpdxPackage>()
Unexecuted instantiation: cmSpdxRelationship& cmSbomObject::CastUnchecked<cmSpdxRelationship>()
230
231
  template <typename T>
232
  T const& CastUnchecked() const
233
  {
234
    return *static_cast<T const*>(Interface().Addr());
235
  }
236
237
  ObjectInterface& Interface()
238
0
  {
239
0
    return *static_cast<ObjectInterface*>(Storage());
240
0
  }
241
  ObjectInterface const& Interface() const
242
0
  {
243
0
    return *static_cast<ObjectInterface const*>(Storage());
244
0
  }
245
246
0
  void* Storage() { return &Data.Data; }
247
0
  void const* Storage() const { return &Data.Data; }
248
249
  template <typename U>
250
  U* ptr() noexcept
251
  {
252
    return std::addressof(this->template CastUnchecked<U>());
253
  }
254
255
  template <typename U>
256
  U const* ptr() const noexcept
257
  {
258
    return std::addressof(this->template CastUnchecked<U>());
259
  }
260
261
private:
262
  ObjectStorage::Buffer Data{};
263
};
264
265
template <typename T, typename U = cm::decay_t<T>>
266
U* insert_back(std::vector<cmSbomObject>& vec, T&& obj) noexcept
267
0
{
268
0
  vec.emplace_back(std::forward<U>(obj));
269
0
  return std::addressof(vec.back().CastUnchecked<U>());
270
0
}
Unexecuted instantiation: cmSpdxDocument* insert_back<cmSpdxDocument, cmSpdxDocument>(std::__1::vector<cmSbomObject, std::__1::allocator<cmSbomObject> >&, cmSpdxDocument&&)
Unexecuted instantiation: cmSpdxPackage* insert_back<cmSpdxPackage, cmSpdxPackage>(std::__1::vector<cmSbomObject, std::__1::allocator<cmSbomObject> >&, cmSpdxPackage&&)
Unexecuted instantiation: cmSpdxRelationship* insert_back<cmSpdxRelationship, cmSpdxRelationship>(std::__1::vector<cmSbomObject, std::__1::allocator<cmSbomObject> >&, cmSpdxRelationship&&)