# bounds_t

Class represents a half-open interval with lower and upper bounds. #include <sdlt/bounds.h>

## Syntax

    template<typename LowerT = int, typename UpperT = int>
    struct bounds_t

## Description

bounds_t holds the lower and upper bounds of a half open interval. It is templated to allow the different representations for the lower and upper bounds. Supported types include fixed<NumberT>, aligned<AlignmentT> and integer values. bounds_t models a valid iteration space over a single dimension.

bounds_t can be used to represent an iteration space over the entire extent of a dimension or to restrict iteration space within the extent. n_bounds_t aggregates a number of bounds_t objects to allow construction of multi-demensional subsections restricting multiple extents.

The class interface is compatible with C++ range-based loops to simplify iteration.

Template Argument | Description
--- | ---
    typename LowerT = int
| Type of lower bound. Requirements: type is int, or fixed<NumberT>, or aligned<AlignmentT>
    typename UpperT = int
| Type of upper bound. Requirements: type is int, or fixed<NumberT>, or aligned<AlignmentT>

Member Types | Description
--- | ---
    typedef LowerT lower_type
| Type of the lower bound
    typedef UpperT upper_type
| Type of the upper bound
    typedef implementation-defined iterator
| Iterator type for C++ range-based loops support.

Member | Description
--- | ---
    bounds_t()
| Effects: Constructs bounds_t with uninitialized lower and upper bounds.
    bounds_t(lower_type l, upper_type u)
| Requirements: (u >= l) Effects: Constructs bounds_t representing the half-open interval [l, u)
    bounds_t(const bounds_t & a_other)
| Effects: Constructs bounds_t with lower and upper bounds initialized from those of a_other.
    template<typename OtherLowerT,
             typename OtherUpperT>
    bounds_t(const bounds_t<OtherLowerT,
                     OtherUpperT> & a_other)
| Requirements: OtherLowerT and OtherUpperT can legally be converted to lower_type and upper_type. For example it would be illegal to convert an int to fixed<8>(). Effects: Constructs bounds_t with lower and upper bounds initialized from those of a_other.
    void set(lower_type l, upper_type u)
| Effects: Set index of the inclusive lower bound and the index of the exclusive upper bound.
    void set_lower(lower_type a_lower)
| Effects: Set index of the inclusive lower bound
    void set_upper(upper_type a_upper)
| Effects: Set index of the exclusive upper bound
    lower_type lower() const
| Returns: index of the inclusive lower bound
    upper_type upper() const
| Returns: index of the exclusive upper bound
    iterator begin() const
| Returns: index iterator for the inclusive lower bound. NOTE: C++11 range-based loops require begin() & end()
    iterator end() const
| Returns: index iterator for the exclusive upper bound. NOTE: C++11 range-based loops require begin() & end()
    auto width() const
| Effects: Determine width of iteration space inside the half open interval between lower() and upper() bounds. Returns: upper() – lower() NOTE: the return type depends on resulting type of a subtraction between the types of upper() and lower().
    template<typename OtherLowerT,
             typename OtherUpperT>
    bool contains(const bounds_t<OtherLowerT,
                    OtherUpperT> &a_other) const
| Effects: Determine if interval of a_other is entirely contained inside this object’s bounds Returns: (a_other.lower() >= lower() && a_other.upper() <= upper())
    template<typename T>
    auto operator + (const T &offset) const
| Effects: create a new bounds_t instance with offset added to both lower and upper bounds. Returns: bounds(lower() + offset, upper()+offset) NOTE: The lower_type and upper_type of the returned bound_t maybe different as result of addition of the offset.
    template<typename T>
    auto operator - (const T & offset) const
| Effects: create a new bounds_t instance with offset subtracted from both lower and upper bounds. Returns: bounds(lower() - offset, upper()-offset) NOTE: The lower_type and upper_type of the returned object maybe different as result of subtraction of T.
    bool operator == (const bounds_t &a_other) const
| Effects: Equality comparison with same-typed bounds_t object Returns: (lower() == a_other.lower() && upper() == a_other.upper())
    template<typename OtherLowerT,
             typename OtherUpperT>
    bool operator == (
     const bounds_t<OtherLowerT,
                    OtherUpperT> &a_other) const
| Effects: Equality comparison with bounds_t object of different lower_type or upper_type. Returns: (lower() == a_other.lower() && upper() == a_other.upper())
    bool operator != (const bounds_t &) const
| Effects: Inequality comparison with same-typed bounds_t object Returns: (lower() != a_other.lower() || upper() != a_other.upper())
    template<typename OtherLowerT,
             typename OtherUpperT>
    bool operator != (
     const bounds_t<OtherLowerT,
                    OtherUpperT> &a_other) const
| Effects: Inequality comparison with with bounds_t object of different lower_type or upper_type Returns: (lower() != a_other.lower() || upper() != a_other.upper())

Friend Function | Description
--- | ---
    std::ostream& operator << (std::ostream& a_output_stream, const bounds_t &a_bounds)
| Effects: append string representation of bounds_t lower and upper values to a_output_stream Returns: reference to a_output_stream for chained calls

Range-based loops support

The bounds_t provides begin() and end() methods returning iterators to enable C++11 range-based loops. The may save quite some typing and improve code clarity when iterating over bounds of a multidimensional container.

Compare:

    auto ca = image_container.const_access();
    auto b0 = bounds_d<0>(ca);
    auto b1 = bounds_d<1>(ca);
    for (auto y = b0.lower(); y < b0.upper(); ++y)
        for (auto x = b1.lower(); x < b1.upper(); ++x) {
              RGBAs pixel = ca[y][x];
                // …
        }

and

    auto ca = image_container.const_access();
    for (auto y: bounds_d<0>(ca))
        for (auto x: bounds_d<1>(ca)) {
              RGBAs pixel = ca[y][x];
                // …
        }

Note that iterator only gives an index value within the bounds, not an object value. It is expected to be used to index into accessors like in example above.

Parent topic: Bounds