Home
ObjexxFCL 4.2
 

Index Ranges

As in Fortran, each dimension of an Array can be given an arbitrary index range. An index range is specified by its lower and upper indices. The ObjexxFCL IndexRange class provides this index range capability.

IndexRanges and rarely used explicitly in application code since curly brace notation of the form {low,high} is more convenient.

Construction

Default constructors create zero-sized ranges [1,0].

Copy constructors are available for all IndexRange types.

Upper index constructors taking a single argument create ranges with a lower index of 1. The upper index argument can be any value convertible to int or an underscore, _, (an instance of Omit) to indicate an unbounded upper index (for the last dimension of assumed-size argument arrays).

Index range constructors taking lower and upper index arguments create ranges with the specified range. The lower and upper index arguments can be any value convertible to int. The upper index argument can also be and underscore, _, to indicate it is unbounded.

Here are some sample IndexRange constructors:

IndexRange I; // Default construction
IndexRange I( 10 ); // [1,10]
IndexRange I( -5, 5 ); // [-5,5]
IndexRange I( _ ); // [1,unbounded]
IndexRange I( 0, _ ); // [0,unbounded]
				

Assignment

IndexRanges assignment operators and functions parallel the constructors. Assignments with the = operator match the single argument constructors and the assign member functions parallel the upper index and index range constructors. Single argument l and u member functions can be used to assign just the lower or upper index, respectively.

Functions

The lower and upper indices of an IndexRange can be accessed with the l and u member functions and the size with the size member function:

IndexRange I( -5, 5 ); // [-5,5]
std::cout << I.l() << std::endl; // Prints -5
std::cout << I.u() << std::endl; // Prints 5
std::cout << I.size() << std::endl; // Prints 11

A number of predicate (boolean) functions are available for IndexRanges, including initialized, bounded, unbounded, and legal. You can also ask an IndexRange whether it contains an index or another range or whether it intersects another range.

The contain and intersect modifying member functions will modify an IndexRange to contain a specified index or range or to intersect a specified range, respectively. The clear member function will clear an IndexRange back to a default-constructed state.

You can compare two index ranges with the operators { ==, !=, >, >=, <, <= }.

Notes on IndexRanges

  • An index range is indicated by [l,u] in the following notes.
  • A zero-sized IndexRange is indicated by a range of the form [l,l-1].
  • An unbounded IndexRange has an unknown upper extent and is indicated by a range of the form [l,l-2] and is generally specified by passing an underscore, _, as the upper index. Such an IndexRange includes all indices >= l. The size of an unbounded IndexRange is set to the constant npos defined in IndexRange. The IndexRange member functions bounded and unbounded can be used to test for this condition.
  • IndexRange has a number of useful functions to query the lower and upper indices, check whether it contains a given index or intersects another IndexRange, and functions that can modify it such as the contain and intersect functions.
  • IndexRanges are indexed by the int type.
  • On platforms with a 32-bit int:
    • l is limited to the range: [-2147483646,2147483647]
    • u is limited to the range: [-2147483648,2147483647]
    Violations of these ranges are detected in assertion-enabled debug builds.
  • l - 2 <= u is required.
  • u can be l - 1 for zero-sized range and l - 2 for unbounded-upper range.
  • The size of an unbounded IndexRange is defined as IndexRange::npos.