/// /// \file Framework/Label.hpp /// /// Label and associated classes for decorating a stream of elements. /// /// \copyright /// Copyright (c) 2014-2015 Josh Blum /// 2019 Nicholas Corgan /// SPDX-License-Identifier: BSL-1.0 /// #pragma once #include #include #include namespace Pothos { /*! * A Label decorates a stream of information with meta-data. * The label's data is an Object with arbitrary contents. * The label's index identifies an element in a stream. */ class POTHOS_API Label { public: //! Create an empty label with null data and zero index. Label(void); //! Create a label with specified data of ValueType and index template Label(const std::string &id, ValueType &&data, const unsigned long long index, const size_t width = 1); /*! * Create a new label with an adjusted index and width. * Example convert bytes to elements: newLbl = lbl.toAdjusted(1, elemSize); * Example convert elements to bytes: newLbl = lbl.toAdjusted(elemSize, 1); * \param mult a positive multiplier (default 1) * \param div a positive divider (default 1) * \return a copy of this label with an adjusted position */ template Label toAdjusted(const MultType &mult, const DivType &div) const; /*! * Adjust the index and width based on a multiplier/divider. * \param mult a positive multiplier (default 1) * \param div a positive divider (default 1) * \return a reference to this label */ template Label &adjust(const MultType &mult, const DivType &div); /*! * The identifier describes the label's type, meaning, or purpose. * Identifiers only have meaning in the context of the blocks * that are producing and consuming them. So any given pair of blocks * need to agree on a particular set of identifiers and their meanings. */ std::string id; /*! * The data can be anything that can be held by Object. */ Object data; /*! * The index specifies an offset into a buffer of elements. * To associate with the first element of a buffer, index should be 0. * To associate with the Nth element of a buffer, index should be N-1. */ unsigned long long index; /*! * The width specifies the number of elements to which this label applies. * Width applies to every element from [index to index+width-1] inclusive. * The default value of width is 1, and it may not take the value zero. */ size_t width; //! support for sorting Labels by index bool operator<(const Label &other) const; //! Serialization support template void serialize(Archive & ar, const unsigned int version); }; //! Are these two labels equivalent? all fields must be equal inline bool operator==(const Label &rhs, const Label &lhs); //! Are these two labels not equivalent? at least one field must not be equal inline bool operator!=(const Label &rhs, const Label &lhs); /*! * LabelIteratorRange represents a sorted range of labels. * It has the standard iterator interface begin()/end(). */ class POTHOS_API LabelIteratorRange { public: //! Const Label iterator type typedef const Label* const_iterator; //! Create an empty/invalid LabelIteratorRange LabelIteratorRange(void); //! Create a LabelIteratorRange from a begin() and end() iterator template LabelIteratorRange(const IterType &begin, const IterType &end); //! Create a LabelIteratorRange from an existing range template LabelIteratorRange(const RangeType &range); //! Get the beginning of the iterator range (inclusive) const_iterator begin(void) const; //! Get the end of the iterator range (exclusive) const_iterator end(void) const; private: const_iterator _begin; const_iterator _end; }; } //namespace Pothos template Pothos::Label::Label(const std::string &id, ValueType &&data, const unsigned long long index, const size_t width): id(id), data(Object(std::forward(data))), index(index), width(width) { return; } template Pothos::Label Pothos::Label::toAdjusted(const MultType &mult, const DivType &div) const { Pothos::Label newLabel(*this); newLabel.adjust(mult, div); return newLabel; } template Pothos::Label &Pothos::Label::adjust(const MultType &mult, const DivType &div) { this->index *= mult; this->width *= mult; this->index /= div; this->width /= div; return *this; } inline bool Pothos::operator==(const Label &rhs, const Label &lhs) { return rhs.index == lhs.index and rhs.width == lhs.width and rhs.id == lhs.id and rhs.data == lhs.data; } inline bool Pothos::operator!=(const Label &rhs, const Label &lhs) { return !(rhs == lhs); } inline bool Pothos::Label::operator<(const Label &other) const { return this->index < other.index; } template Pothos::LabelIteratorRange::LabelIteratorRange(const IterType &begin, const IterType &end): _begin(begin), _end(end) { return; } template Pothos::LabelIteratorRange::LabelIteratorRange(const RangeType &range): _begin(range.data()), _end(range.data() + range.size()) { return; } inline Pothos::LabelIteratorRange::const_iterator Pothos::LabelIteratorRange::begin(void) const { return _begin; } inline Pothos::LabelIteratorRange::const_iterator Pothos::LabelIteratorRange::end(void) const { return _end; }