You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
4.8 KiB
C++

/*=========================================================================
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 <cassert> // For inline assert for bounds checked methods.
#include <cmath> // for std::abs() with float overloads
#include <cstdlib> // for std::abs() with int overloads
template <typename T, int Size>
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<T, Size>& 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 <typename TR>
vtkTuple<TR, Size> Cast() const
{
vtkTuple<TR, Size> result;
for (int i = 0; i < Size; ++i)
{
result[i] = static_cast<TR>(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 <typename A, int Size>
ostream& operator<<(ostream& out, const vtkTuple<A, Size>& 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 <int Size>
ostream& operator<<(ostream& out, const vtkTuple<unsigned char, Size>& t)
{
out << "(";
bool first = true;
for (int i = 0; i < Size; ++i)
{
if (first)
{
first = false;
}
else
{
out << ", ";
}
out << static_cast<int>(t[i]);
}
out << ")";
return out;
}
//@}
//@{
/**
* Equality operator performs an equality check on each component.
*/
template <typename A, int Size>
bool operator==(const vtkTuple<A, Size>& t1, const vtkTuple<A, Size>& t2)
{
for (int i = 0; i < Size; ++i)
{
if (t1[i] != t2[i])
{
return false;
}
}
return true;
}
//@}
/**
* Inequality for vector type.
*/
template <typename A, int Size>
bool operator!=(const vtkTuple<A, Size>& t1, const vtkTuple<A, Size>& t2)
{
return !(t1 == t2);
}
#endif // vtkTuple_h
// VTK-HeaderTest-Exclude: vtkTuple.h