CatapultServer  v0.5.0.1 (Elephant)
EntityRange.h
Go to the documentation of this file.
1 
21 #pragma once
23 #include "catapult/exceptions.h"
24 #include <memory>
25 #include <vector>
26 
27 namespace catapult { namespace model {
28 
30  template<typename TEntity>
31  class EntityRange : public utils::MoveOnly {
32  public:
33  using value_type = TEntity;
34 
35  private:
36  // region SubRange
37 
38  class SubRange {
39  public:
41  {}
42 
43  explicit SubRange(size_t numBytes) : m_numBytes(numBytes)
44  {}
45 
47  : m_numBytes(rhs.m_numBytes)
48  , m_entities(std::move(rhs.m_entities)) {
49  rhs.reset();
50  }
51 
52  public:
54  m_numBytes = rhs.m_numBytes;
55  m_entities = std::move(rhs.m_entities);
56  rhs.reset();
57  return *this;
58  }
59 
60  public:
61  constexpr bool empty() const {
62  return 0 == m_numBytes;
63  }
64 
65  size_t size() const {
66  return m_entities.size();
67  }
68 
69  constexpr size_t totalSize() const {
70  return m_numBytes;
71  }
72 
73  constexpr auto& entities() const {
74  return m_entities;
75  }
76 
77  public:
78  auto& entities() {
79  return m_entities;
80  }
81 
82  void reset() {
83  m_numBytes = 0;
84  m_entities.clear();
85  }
86 
87  private:
88  size_t m_numBytes;
89  std::vector<TEntity*> m_entities;
90  };
91 
92  // endregion
93 
94  // region SingleBufferRange
95 
96  class SingleBufferRange : public SubRange {
97  public:
99  {}
100 
101  SingleBufferRange(size_t dataSize, const std::vector<size_t>& offsets)
102  : SubRange(dataSize)
103  , m_buffer(dataSize) {
104  for (auto offset : offsets)
105  SubRange::entities().push_back(reinterpret_cast<TEntity*>(&m_buffer[offset]));
106  }
107 
108  SingleBufferRange(const uint8_t* pData, size_t dataSize, const std::vector<size_t>& offsets)
109  : SingleBufferRange(dataSize, offsets) {
110  std::memcpy(m_buffer.data(), pData, dataSize);
111  }
112 
113  public:
114  uint8_t* data() {
115  return m_buffer.data();
116  }
117 
118  private:
119  const uint8_t* data() const {
120  return m_buffer.data();
121  }
122 
123  public:
124  std::vector<std::shared_ptr<TEntity>> detachEntities() {
125  std::vector<std::shared_ptr<TEntity>> entities(SubRange::size());
126  auto offsets = generateOffsets();
127  auto pBufferShared = std::make_shared<decltype(m_buffer)>(std::move(m_buffer));
128 
129  size_t i = 0;
130  for (auto offset : offsets) {
131  auto pEntity = reinterpret_cast<TEntity*>(&(*pBufferShared)[offset]);
132  entities[i++] = std::shared_ptr<TEntity>(pEntity, [pBufferShared](const auto*) {});
133  }
134 
135  return entities;
136  }
137 
138  public:
141  }
142 
143  private:
144  std::vector<size_t> generateOffsets() const {
145  size_t i = 0;
146  std::vector<size_t> offsets(SubRange::size());
147  for (const auto* pEntity : SubRange::entities())
148  offsets[i++] = static_cast<size_t>(reinterpret_cast<const uint8_t*>(pEntity) - data());
149 
150  return offsets;
151  }
152 
153  private:
154  std::vector<uint8_t> m_buffer;
155  };
156 
157  // endregion
158 
159  // region SingleEntityRange
160 
161  class SingleEntityRange : public SubRange {
162  public:
164  {}
165 
166  explicit SingleEntityRange(std::unique_ptr<TEntity>&& pEntity)
167  : SubRange(pEntity->Size)
168  , m_pSingleEntity(std::move(pEntity)) {
169  SubRange::entities().push_back(m_pSingleEntity.get());
170  }
171 
172  public:
173  std::vector<std::shared_ptr<TEntity>> detachEntities() {
174  std::vector<std::shared_ptr<TEntity>> entities(1);
175  entities[0] = std::move(m_pSingleEntity);
176  return entities;
177  }
178 
180  return SingleBufferRange(reinterpret_cast<const uint8_t*>(m_pSingleEntity.get()), SubRange::totalSize(), { 0 });
181  }
182 
183  private:
184  std::shared_ptr<TEntity> m_pSingleEntity;
185  };
186 
187  // endregion
188 
189  // region MultiBufferRange
190 
191  class MultiBufferRange : public SubRange {
192  public:
194  {}
195 
196  explicit MultiBufferRange(std::vector<EntityRange>&& ranges)
197  : SubRange(CalculateTotalSize(ranges))
198  , m_ranges(std::move(ranges)) {
199  for (auto& range : m_ranges)
200  for (auto& entity : range)
201  SubRange::entities().push_back(&entity);
202  }
203 
204  public:
205  std::vector<std::shared_ptr<TEntity>> detachEntities() {
206  std::vector<std::shared_ptr<TEntity>> allEntities;
207  allEntities.reserve(SubRange::size());
208 
209  for (auto& range : m_ranges) {
210  auto rangeEntities = range.detachSubRangeEntities();
211  allEntities.insert(
212  allEntities.end(),
213  std::make_move_iterator(rangeEntities.begin()),
214  std::make_move_iterator(rangeEntities.end()));
215  }
216 
217  return allEntities;
218  }
219 
220  public:
222  std::vector<EntityRange> copyRanges;
223  for (const auto& range : m_ranges)
224  copyRanges.push_back(range.copySubRange());
225 
226  return MultiBufferRange(std::move(copyRanges));
227  }
228 
229  private:
230  static size_t CalculateTotalSize(const std::vector<EntityRange>& ranges) {
231  size_t totalSize = 0;
232  for (const auto& range : ranges)
233  totalSize += range.totalSize();
234 
235  return totalSize;
236  }
237 
238  private:
239  std::vector<EntityRange> m_ranges;
240  };
241 
242  // endregion
243 
244  public:
247  {}
248 
249  private:
250  explicit EntityRange(SingleBufferRange&& subRange)
251  : m_singleBufferRange(std::move(subRange))
252  {}
253 
254  explicit EntityRange(SingleEntityRange&& subRange)
255  : m_singleEntityRange(std::move(subRange))
256  {}
257 
259  : m_multiBufferRange(std::move(subRange))
260  {}
261 
262  public:
265  static EntityRange PrepareFixed(size_t numElements, uint8_t** ppRangeData = nullptr) {
266  std::vector<size_t> offsets(numElements);
267  for (auto i = 0u; i < numElements; ++i)
268  offsets[i] = i * sizeof(TEntity);
269 
270  auto range = EntityRange(SingleBufferRange(numElements * sizeof(TEntity), offsets));
271  if (ppRangeData)
272  *ppRangeData = range.m_singleBufferRange.data();
273 
274  return range;
275  }
276 
278  static EntityRange CopyFixed(const uint8_t* pData, size_t numElements) {
279  uint8_t* pRangeData;
280  auto range = PrepareFixed(numElements, &pRangeData);
281  std::memcpy(pRangeData, pData, range.totalSize());
282  return range;
283  }
284 
287  static EntityRange CopyVariable(const uint8_t* pData, size_t dataSize, const std::vector<size_t>& offsets) {
288  return EntityRange(SingleBufferRange(pData, dataSize, offsets));
289  }
290 
292  static EntityRange FromEntity(std::unique_ptr<TEntity>&& pEntity) {
293  return EntityRange(SingleEntityRange(std::move(pEntity)));
294  }
295 
297  static EntityRange MergeRanges(std::vector<EntityRange>&& ranges) {
298  return EntityRange(MultiBufferRange(std::move(ranges)));
299  }
300 
301  public:
303  bool empty() const {
304  return subRange().empty();
305  }
306 
308  size_t size() const {
309  return subRange().size();
310  }
311 
313  size_t totalSize() const {
314  return subRange().totalSize();
315  }
316 
317  // region iterators
318  public:
320  template<typename TIterator, typename TIteratorEntity>
321  class iterator {
322  public:
323  using difference_type = typename TIterator::difference_type;
324  using value_type = std::remove_const_t<TIteratorEntity>;
325  using pointer = TIteratorEntity*;
326  using reference = TIteratorEntity&;
327  using iterator_category = std::bidirectional_iterator_tag;
328 
329  public:
331  explicit iterator(TIterator current) : m_current(current)
332  {}
333 
334  public:
336  bool operator==(const iterator& rhs) const {
337  return m_current == rhs.m_current;
338  }
339 
341  bool operator!=(const iterator& rhs) const {
342  return !(*this == rhs);
343  }
344 
345  public:
348  ++m_current;
349  return *this;
350  }
351 
354  auto copy = *this;
355  ++m_current;
356  return copy;
357  }
358 
361  --m_current;
362  return *this;
363  }
364 
367  auto copy = *this;
368  --m_current;
369  return copy;
370  }
371 
372  public:
375  return *this->operator->();
376  }
377 
379  pointer operator->() const {
380  return *m_current;
381  }
382 
385  return *this->operator->();
386  }
387 
390  return *m_current;
391  }
392 
393  private:
394  TIterator m_current;
395  };
396 
397  private:
398  template<typename TIterator>
399  static auto make_const_iterator(TIterator current) {
400  return iterator<TIterator, const value_type>(current);
401  }
402 
403  template<typename TIterator>
404  static auto make_iterator(TIterator current) {
405  return iterator<TIterator, value_type>(current);
406  }
407 
408  public:
410  auto cbegin() const {
411  return make_const_iterator(subRange().entities().cbegin());
412  }
413 
415  auto cend() const {
416  return make_const_iterator(subRange().entities().cend());
417  }
418 
420  auto begin() const {
421  return cbegin();
422  }
423 
425  auto end() const {
426  return cend();
427  }
428 
430  auto begin() {
431  return make_iterator(subRange().entities().begin());
432  }
433 
435  auto end() {
436  return make_iterator(subRange().entities().end());
437  }
438 
439  // endregion
440 
441  public:
444  const auto* data() const {
446  return empty() ? nullptr : &*cbegin();
447  }
448 
451  auto* data() {
453  return empty() ? nullptr : &*begin();
454  }
455 
456  private:
457  void requireContiguousData() const {
458  if (!m_multiBufferRange.empty())
459  CATAPULT_THROW_RUNTIME_ERROR("data is not accessible when range is composed of non-contiguous data");
460  }
461 
462  public:
464  static EntityRange CopyRange(const EntityRange& rhs) {
465  return rhs.copySubRange();
466  }
467 
470  static std::vector<std::shared_ptr<TEntity>> ExtractEntitiesFromRange(EntityRange&& range) {
471  return range.detachSubRangeEntities();
472  }
473 
474  private:
475  const SubRange& subRange() const {
476  return const_cast<EntityRange&>(*this).subRange();
477  }
478 
479  SubRange& subRange() {
480  SubRange* pSubRange;
481  activeSubRangeAction([&pSubRange](auto& subRange) { pSubRange = &subRange; });
482  return *pSubRange;
483  }
484 
485  auto copySubRange() const {
486  return activeSubRangeAction([](const auto& subRange) { return EntityRange(subRange.copy()); });
487  }
488 
490  return activeSubRangeAction([](auto& subRange) {
491  auto entities = subRange.detachEntities();
492  subRange.reset();
493  return entities;
494  });
495  }
496 
497  template<typename TFunc>
498  auto activeSubRangeAction(TFunc func) const {
499  return const_cast<EntityRange&>(*this).activeSubRangeAction(func);
500  }
501 
502  template<typename TFunc>
503  auto activeSubRangeAction(TFunc func) {
504  if (!m_singleEntityRange.empty())
505  return func(m_singleEntityRange);
506 
507  if (!m_multiBufferRange.empty())
508  return func(m_multiBufferRange);
509 
510  return func(m_singleBufferRange);
511  }
512 
513  private:
514  friend class MultiBufferRange;
515 
516  private:
517  SingleBufferRange m_singleBufferRange;
518  SingleEntityRange m_singleEntityRange;
520  };
521 
523  template<typename TEntity>
525  auto lhsIter = lhs.cbegin();
526  auto rhsIter = rhs.cbegin();
527  size_t index = 0;
528 
529  while (lhs.cend() != lhsIter && rhs.cend() != rhsIter) {
530  if (*lhsIter != *rhsIter)
531  break;
532 
533  ++index;
534  ++lhsIter;
535  ++rhsIter;
536  }
537 
538  return index;
539  }
540 }}
catapult::model::EntityRange::cbegin
auto cbegin() const
Returns a const iterator that represents the first entity.
Definition: EntityRange.h:410
catapult::model::EntityRange::SubRange::entities
auto & entities()
Definition: EntityRange.h:78
catapult::model::EntityRange::MultiBufferRange::copy
MultiBufferRange copy() const
Definition: EntityRange.h:221
catapult::model::EntityRange::SubRange::operator=
SubRange & operator=(SubRange &&rhs)
Definition: EntityRange.h:53
catapult::model::EntityRange::iterator::operator*
reference operator*() const
Returns a reference to the current entity.
Definition: EntityRange.h:374
catapult::model::EntityRange::MultiBufferRange::MultiBufferRange
MultiBufferRange()
Definition: EntityRange.h:193
catapult::model::EntityRange::requireContiguousData
void requireContiguousData() const
Definition: EntityRange.h:457
catapult::model::EntityRange::SingleBufferRange::m_buffer
std::vector< uint8_t > m_buffer
Definition: EntityRange.h:154
catapult::model::EntityRange::FromEntity
static EntityRange FromEntity(std::unique_ptr< TEntity > &&pEntity)
Creates an entity range around a single entity (pEntity).
Definition: EntityRange.h:292
catapult::model::EntityRange::cend
auto cend() const
Returns a const iterator that represents one past the last entity.
Definition: EntityRange.h:415
catapult::model::EntityRange::MultiBufferRange
Definition: EntityRange.h:191
catapult::model::EntityRange::subRange
const SubRange & subRange() const
Definition: EntityRange.h:475
exceptions.h
catapult::model::EntityRange::SingleBufferRange::detachEntities
std::vector< std::shared_ptr< TEntity > > detachEntities()
Definition: EntityRange.h:124
catapult::model::EntityRange::SubRange::entities
constexpr auto & entities() const
Definition: EntityRange.h:73
catapult::model::EntityRange::SubRange::m_numBytes
size_t m_numBytes
Definition: EntityRange.h:88
catapult::model::EntityRange::CopyRange
static EntityRange CopyRange(const EntityRange &rhs)
Creates an entity range by making a copy of an existing range rhs.
Definition: EntityRange.h:464
catapult::model::EntityRange::detachSubRangeEntities
auto detachSubRangeEntities()
Definition: EntityRange.h:489
catapult::model::EntityRange::EntityRange
EntityRange(SingleBufferRange &&subRange)
Definition: EntityRange.h:250
catapult::model::EntityRange::iterator::value_type
std::remove_const_t< TIteratorEntity > value_type
Definition: EntityRange.h:324
catapult::model::EntityRange::data
auto * data()
Definition: EntityRange.h:451
catapult::model::EntityRange::SingleEntityRange::m_pSingleEntity
std::shared_ptr< TEntity > m_pSingleEntity
Definition: EntityRange.h:184
catapult::model::EntityRange::SubRange::SubRange
SubRange()
Definition: EntityRange.h:40
catapult::model::EntityRange::ExtractEntitiesFromRange
static std::vector< std::shared_ptr< TEntity > > ExtractEntitiesFromRange(EntityRange &&range)
Definition: EntityRange.h:470
catapult::model::EntityRange::iterator::operator->
pointer operator->() const
Returns a pointer to the current entity.
Definition: EntityRange.h:379
catapult::model::EntityRange::SingleBufferRange::SingleBufferRange
SingleBufferRange(size_t dataSize, const std::vector< size_t > &offsets)
Definition: EntityRange.h:101
catapult::model::EntityRange::MultiBufferRange::detachEntities
std::vector< std::shared_ptr< TEntity > > detachEntities()
Definition: EntityRange.h:205
catapult::model::EntityRange::SingleEntityRange::detachEntities
std::vector< std::shared_ptr< TEntity > > detachEntities()
Definition: EntityRange.h:173
catapult::model::EntityRange::SubRange
Definition: EntityRange.h:38
catapult::model::EntityRange::empty
bool empty() const
Gets a value indicating whether or not this range is empty.
Definition: EntityRange.h:303
catapult::model::EntityRange< KeyType >::value_type
KeyType value_type
Definition: EntityRange.h:33
catapult::model::EntityRange::MultiBufferRange
friend class MultiBufferRange
Definition: EntityRange.h:514
catapult::model::EntityRange::iterator::operator*
reference operator*()
Returns a reference to the current entity.
Definition: EntityRange.h:384
catapult::model::EntityRange::iterator::iterator_category
std::bidirectional_iterator_tag iterator_category
Definition: EntityRange.h:327
catapult::model::EntityRange::end
auto end()
Returns an iterator that represents one past the last entity.
Definition: EntityRange.h:435
catapult::model::EntityRange::iterator::operator->
pointer operator->()
Returns a pointer to the current entity.
Definition: EntityRange.h:389
catapult::model::EntityRange::MultiBufferRange::m_ranges
std::vector< EntityRange > m_ranges
Definition: EntityRange.h:239
catapult::model::EntityRange
Represents a range of entities.
Definition: EntityRange.h:31
catapult::model::EntityRange::iterator::operator--
iterator operator--(int)
Advances the iterator to the previous position.
Definition: EntityRange.h:366
catapult::model::EntityRange::SingleBufferRange::generateOffsets
std::vector< size_t > generateOffsets() const
Definition: EntityRange.h:144
catapult::model::EntityRange::end
auto end() const
Returns a const iterator that represents one past the last entity.
Definition: EntityRange.h:425
catapult::model::EntityRange::CopyFixed
static EntityRange CopyFixed(const uint8_t *pData, size_t numElements)
Creates an entity range around numElements fixed size elements pointed to by pData.
Definition: EntityRange.h:278
catapult::model::EntityRange::begin
auto begin() const
Returns a const iterator that represents the first entity.
Definition: EntityRange.h:420
catapult::model::EntityRange::SingleEntityRange::SingleEntityRange
SingleEntityRange(std::unique_ptr< TEntity > &&pEntity)
Definition: EntityRange.h:166
catapult::model::EntityRange::iterator::operator!=
bool operator!=(const iterator &rhs) const
Returns true if this iterator and rhs are not equal.
Definition: EntityRange.h:341
catapult::model::EntityRange::SingleBufferRange::copy
SingleBufferRange copy() const
Definition: EntityRange.h:139
catapult::model::EntityRange::iterator::operator++
iterator & operator++()
Advances the iterator to the next position.
Definition: EntityRange.h:347
catapult::model::EntityRange::make_const_iterator
static auto make_const_iterator(TIterator current)
Definition: EntityRange.h:399
catapult::model::EntityRange::iterator::difference_type
typename TIterator::difference_type difference_type
Definition: EntityRange.h:323
catapult::model::EntityRange::SingleEntityRange
Definition: EntityRange.h:161
catapult::model::EntityRange::SubRange::SubRange
SubRange(size_t numBytes)
Definition: EntityRange.h:43
catapult::model::EntityRange::PrepareFixed
static EntityRange PrepareFixed(size_t numElements, uint8_t **ppRangeData=nullptr)
Definition: EntityRange.h:265
catapult::model::EntityRange::EntityRange
EntityRange(SingleEntityRange &&subRange)
Definition: EntityRange.h:254
catapult::model::EntityRange::CopyVariable
static EntityRange CopyVariable(const uint8_t *pData, size_t dataSize, const std::vector< size_t > &offsets)
Definition: EntityRange.h:287
catapult::model::EntityRange::MergeRanges
static EntityRange MergeRanges(std::vector< EntityRange > &&ranges)
Merges all ranges into a single range.
Definition: EntityRange.h:297
catapult::model::EntityRange::make_iterator
static auto make_iterator(TIterator current)
Definition: EntityRange.h:404
catapult::model::EntityRange::EntityRange
EntityRange()
Creates an empty entity range.
Definition: EntityRange.h:246
catapult::model::EntityRange::subRange
SubRange & subRange()
Definition: EntityRange.h:479
catapult::model::EntityRange::SubRange::size
size_t size() const
Definition: EntityRange.h:65
catapult::model::EntityRange::begin
auto begin()
Returns an iterator that represents the first entity.
Definition: EntityRange.h:430
catapult::model::EntityRange::SubRange::SubRange
SubRange(SubRange &&rhs)
Definition: EntityRange.h:46
catapult::model::EntityRange::iterator::operator==
bool operator==(const iterator &rhs) const
Returns true if this iterator and rhs are equal.
Definition: EntityRange.h:336
catapult::model::EntityRange::size
size_t size() const
Gets the size of this range.
Definition: EntityRange.h:308
catapult::model::EntityRange::data
const auto * data() const
Definition: EntityRange.h:444
catapult::model::EntityRange::totalSize
size_t totalSize() const
Gets the total size of the range in bytes.
Definition: EntityRange.h:313
catapult::model::EntityRange::iterator::iterator
iterator(TIterator current)
Creates an iterator around current.
Definition: EntityRange.h:331
catapult::model::EntityRange::iterator::operator--
iterator & operator--()
Advances the iterator to the previous position.
Definition: EntityRange.h:360
catapult::utils::MoveOnly
A class that can be moved but not copied.
Definition: NonCopyable.h:43
catapult::model::EntityRange::iterator::operator++
iterator operator++(int)
Advances the iterator to the next position.
Definition: EntityRange.h:353
catapult::model::EntityRange::MultiBufferRange::CalculateTotalSize
static size_t CalculateTotalSize(const std::vector< EntityRange > &ranges)
Definition: EntityRange.h:230
catapult::model::EntityRange::iterator::m_current
TIterator m_current
Definition: EntityRange.h:394
catapult::model::EntityRange::iterator::reference
TIteratorEntity & reference
Definition: EntityRange.h:326
catapult::model::EntityRange::copySubRange
auto copySubRange() const
Definition: EntityRange.h:485
CATAPULT_THROW_RUNTIME_ERROR
#define CATAPULT_THROW_RUNTIME_ERROR(MESSAGE)
Macro used to throw a catapult runtime error.
Definition: exceptions.h:167
catapult::model::EntityRange::SingleBufferRange::data
uint8_t * data()
Definition: EntityRange.h:114
catapult::model::EntityRange::SingleBufferRange::SingleBufferRange
SingleBufferRange(const uint8_t *pData, size_t dataSize, const std::vector< size_t > &offsets)
Definition: EntityRange.h:108
catapult::model::EntityRange::SingleBufferRange
Definition: EntityRange.h:96
catapult::model::EntityRange::MultiBufferRange::MultiBufferRange
MultiBufferRange(std::vector< EntityRange > &&ranges)
Definition: EntityRange.h:196
catapult::model::EntityRange::activeSubRangeAction
auto activeSubRangeAction(TFunc func) const
Definition: EntityRange.h:498
catapult::model::EntityRange::iterator
Entity range iterator.
Definition: EntityRange.h:321
catapult::model::FindFirstDifferenceIndex
size_t FindFirstDifferenceIndex(const EntityRange< TEntity > &lhs, const EntityRange< TEntity > &rhs)
Compares two entity ranges (lhs and rhs) and returns the index of the first non-equal element.
Definition: EntityRange.h:524
catapult
Definition: AddressExtractionExtension.cpp:28
catapult::model::EntityRange::SubRange::reset
void reset()
Definition: EntityRange.h:82
catapult::model::EntityRange::SingleBufferRange::data
const uint8_t * data() const
Definition: EntityRange.h:119
catapult::model::EntityRange::SubRange::totalSize
constexpr size_t totalSize() const
Definition: EntityRange.h:69
catapult::model::EntityRange::SingleBufferRange::SingleBufferRange
SingleBufferRange()
Definition: EntityRange.h:98
catapult::model::EntityRange::SingleEntityRange::copy
SingleBufferRange copy() const
Definition: EntityRange.h:179
catapult::model::EntityRange::iterator::pointer
TIteratorEntity * pointer
Definition: EntityRange.h:325
catapult::model::EntityRange::EntityRange
EntityRange(MultiBufferRange &&subRange)
Definition: EntityRange.h:258
catapult::model::EntityRange::SubRange::m_entities
std::vector< TEntity * > m_entities
Definition: EntityRange.h:89
catapult::model::EntityRange::m_multiBufferRange
MultiBufferRange m_multiBufferRange
Definition: EntityRange.h:519
catapult::model::EntityRange::m_singleBufferRange
SingleBufferRange m_singleBufferRange
Definition: EntityRange.h:517
catapult::model::EntityRange::SingleEntityRange::SingleEntityRange
SingleEntityRange()
Definition: EntityRange.h:163
catapult::model::EntityRange::m_singleEntityRange
SingleEntityRange m_singleEntityRange
Definition: EntityRange.h:518
catapult::model::EntityRange::activeSubRangeAction
auto activeSubRangeAction(TFunc func)
Definition: EntityRange.h:503
catapult::model::EntityRange::SubRange::empty
constexpr bool empty() const
Definition: EntityRange.h:61
NonCopyable.h