/*========================================================================= Program: Visualization Toolkit Module: vtkTuple.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkTuple * @brief templated base type for containers of constant size. * * * This class is a templated data type for storing and manipulating tuples. */ #ifndef vtkTuple_h #define vtkTuple_h #include "vtkIOStream.h" // For streaming operators #include "vtkSystemIncludes.h" #include // For inline assert for bounds checked methods. #include // for std::abs() with float overloads #include // for std::abs() with int overloads template class vtkTuple { public: /** * The default constructor does not initialize values. If initializtion is * desired, this should be done explicitly using the constructors for scalar * initialization, or other suitable constructors taking arguments. */ vtkTuple() {} /** * Initialize all of the tuple's elements with the supplied scalar. */ explicit vtkTuple(const T& scalar) { for (int i = 0; i < Size; ++i) { this->Data[i] = scalar; } } /** * Initialize the tuple's elements with the elements of the supplied array. * Note that the supplied pointer must contain at least as many elements as * the tuple, or it will result in access to out of bounds memory. */ explicit vtkTuple(const T* init) { for (int i = 0; i < Size; ++i) { this->Data[i] = init[i]; } } /** * Get the size of the tuple. */ int GetSize() const { return Size; } /** * Get a pointer to the underlying data of the tuple. */ T* GetData() { return this->Data; } const T* GetData() const { return this->Data; } /** * Get a reference to the underlying data element of the tuple. * This works similarly to the way C++ STL containers work. No * bounds checking is performed. */ T& operator[](int i) { return this->Data[i]; } const T& operator[](int i) const { return this->Data[i]; } //@{ /** * Get the value of the tuple at the index specified. Does bounds * checking, similar to the at(i) method of C++ STL containers, but * only when the code is compiled in debug mode. */ T operator()(int i) const { assert("pre: index_in_bounds" && i >= 0 && i < Size); return this->Data[i]; } //@} //@{ /** * Equality operator with a tolerance to allow fuzzy comparisons. */ bool Compare(const vtkTuple& other, const T& tol) const { if (Size != other.GetSize()) { return false; } for (int i = 0; i < Size; ++i) { if (std::abs(this->Data[i] - other.Data[i]) >= tol) { return false; } } return true; } //@} //@{ /** * Cast the tuple to the specified type, returning the result. */ template vtkTuple Cast() const { vtkTuple result; for (int i = 0; i < Size; ++i) { result[i] = static_cast(this->Data[i]); } return result; } //@} protected: //@{ /** * The only thing stored in memory! */ T Data[Size]; //@} }; //@{ /** * Output the contents of a tuple, mainly useful for debugging. */ template ostream& operator<<(ostream& out, const vtkTuple& t) { out << "("; bool first = true; for (int i = 0; i < Size; ++i) { if (first) { first = false; } else { out << ", "; } out << t[i]; } out << ")"; return out; } // Specialize for unsigned char so that we can see the numbers! template ostream& operator<<(ostream& out, const vtkTuple& t) { out << "("; bool first = true; for (int i = 0; i < Size; ++i) { if (first) { first = false; } else { out << ", "; } out << static_cast(t[i]); } out << ")"; return out; } //@} //@{ /** * Equality operator performs an equality check on each component. */ template bool operator==(const vtkTuple& t1, const vtkTuple& t2) { for (int i = 0; i < Size; ++i) { if (t1[i] != t2[i]) { return false; } } return true; } //@} /** * Inequality for vector type. */ template bool operator!=(const vtkTuple& t1, const vtkTuple& t2) { return !(t1 == t2); } #endif // vtkTuple_h // VTK-HeaderTest-Exclude: vtkTuple.h