Label.hpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. ///
  2. /// \file Framework/Label.hpp
  3. ///
  4. /// Label and associated classes for decorating a stream of elements.
  5. ///
  6. /// \copyright
  7. /// Copyright (c) 2014-2015 Josh Blum
  8. /// 2019 Nicholas Corgan
  9. /// SPDX-License-Identifier: BSL-1.0
  10. ///
  11. #pragma once
  12. #include <Pothos/Config.hpp>
  13. #include <Pothos/Object/Object.hpp>
  14. #include <string>
  15. namespace Pothos {
  16. /*!
  17. * A Label decorates a stream of information with meta-data.
  18. * The label's data is an Object with arbitrary contents.
  19. * The label's index identifies an element in a stream.
  20. */
  21. class POTHOS_API Label
  22. {
  23. public:
  24. //! Create an empty label with null data and zero index.
  25. Label(void);
  26. //! Create a label with specified data of ValueType and index
  27. template <typename ValueType>
  28. Label(const std::string &id, ValueType &&data, const unsigned long long index, const size_t width = 1);
  29. /*!
  30. * Create a new label with an adjusted index and width.
  31. * Example convert bytes to elements: newLbl = lbl.toAdjusted(1, elemSize);
  32. * Example convert elements to bytes: newLbl = lbl.toAdjusted(elemSize, 1);
  33. * \param mult a positive multiplier (default 1)
  34. * \param div a positive divider (default 1)
  35. * \return a copy of this label with an adjusted position
  36. */
  37. template <typename MultType, typename DivType>
  38. Label toAdjusted(const MultType &mult, const DivType &div) const;
  39. /*!
  40. * Adjust the index and width based on a multiplier/divider.
  41. * \param mult a positive multiplier (default 1)
  42. * \param div a positive divider (default 1)
  43. * \return a reference to this label
  44. */
  45. template <typename MultType, typename DivType>
  46. Label &adjust(const MultType &mult, const DivType &div);
  47. /*!
  48. * The identifier describes the label's type, meaning, or purpose.
  49. * Identifiers only have meaning in the context of the blocks
  50. * that are producing and consuming them. So any given pair of blocks
  51. * need to agree on a particular set of identifiers and their meanings.
  52. */
  53. std::string id;
  54. /*!
  55. * The data can be anything that can be held by Object.
  56. */
  57. Object data;
  58. /*!
  59. * The index specifies an offset into a buffer of elements.
  60. * To associate with the first element of a buffer, index should be 0.
  61. * To associate with the Nth element of a buffer, index should be N-1.
  62. */
  63. unsigned long long index;
  64. /*!
  65. * The width specifies the number of elements to which this label applies.
  66. * Width applies to every element from [index to index+width-1] inclusive.
  67. * The default value of width is 1, and it may not take the value zero.
  68. */
  69. size_t width;
  70. //! support for sorting Labels by index
  71. bool operator<(const Label &other) const;
  72. //! Serialization support
  73. template<class Archive>
  74. void serialize(Archive & ar, const unsigned int version);
  75. };
  76. //! Are these two labels equivalent? all fields must be equal
  77. inline bool operator==(const Label &rhs, const Label &lhs);
  78. //! Are these two labels not equivalent? at least one field must not be equal
  79. inline bool operator!=(const Label &rhs, const Label &lhs);
  80. /*!
  81. * LabelIteratorRange represents a sorted range of labels.
  82. * It has the standard iterator interface begin()/end().
  83. */
  84. class POTHOS_API LabelIteratorRange
  85. {
  86. public:
  87. //! Const Label iterator type
  88. typedef const Label* const_iterator;
  89. //! Create an empty/invalid LabelIteratorRange
  90. LabelIteratorRange(void);
  91. //! Create a LabelIteratorRange from a begin() and end() iterator
  92. template <typename IterType>
  93. LabelIteratorRange(const IterType &begin, const IterType &end);
  94. //! Create a LabelIteratorRange from an existing range
  95. template <typename RangeType>
  96. LabelIteratorRange(const RangeType &range);
  97. //! Get the beginning of the iterator range (inclusive)
  98. const_iterator begin(void) const;
  99. //! Get the end of the iterator range (exclusive)
  100. const_iterator end(void) const;
  101. private:
  102. const_iterator _begin;
  103. const_iterator _end;
  104. };
  105. } //namespace Pothos
  106. template <typename ValueType>
  107. Pothos::Label::Label(const std::string &id, ValueType &&data, const unsigned long long index, const size_t width):
  108. id(id),
  109. data(Object(std::forward<ValueType>(data))),
  110. index(index),
  111. width(width)
  112. {
  113. return;
  114. }
  115. template <typename MultType, typename DivType>
  116. Pothos::Label Pothos::Label::toAdjusted(const MultType &mult, const DivType &div) const
  117. {
  118. Pothos::Label newLabel(*this);
  119. newLabel.adjust(mult, div);
  120. return newLabel;
  121. }
  122. template <typename MultType, typename DivType>
  123. Pothos::Label &Pothos::Label::adjust(const MultType &mult, const DivType &div)
  124. {
  125. this->index *= mult;
  126. this->width *= mult;
  127. this->index /= div;
  128. this->width /= div;
  129. return *this;
  130. }
  131. inline bool Pothos::operator==(const Label &rhs, const Label &lhs)
  132. {
  133. return
  134. rhs.index == lhs.index and
  135. rhs.width == lhs.width and
  136. rhs.id == lhs.id and
  137. rhs.data == lhs.data;
  138. }
  139. inline bool Pothos::operator!=(const Label &rhs, const Label &lhs)
  140. {
  141. return !(rhs == lhs);
  142. }
  143. inline bool Pothos::Label::operator<(const Label &other) const
  144. {
  145. return this->index < other.index;
  146. }
  147. template <typename IterType>
  148. Pothos::LabelIteratorRange::LabelIteratorRange(const IterType &begin, const IterType &end):
  149. _begin(begin), _end(end)
  150. {
  151. return;
  152. }
  153. template <typename RangeType>
  154. Pothos::LabelIteratorRange::LabelIteratorRange(const RangeType &range):
  155. _begin(range.data()), _end(range.data() + range.size())
  156. {
  157. return;
  158. }
  159. inline Pothos::LabelIteratorRange::const_iterator Pothos::LabelIteratorRange::begin(void) const
  160. {
  161. return _begin;
  162. }
  163. inline Pothos::LabelIteratorRange::const_iterator Pothos::LabelIteratorRange::end(void) const
  164. {
  165. return _end;
  166. }