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.

228 lines
6.1 KiB
C++

/**
* @file
* @brief Basic DataPointer class and its derivates SingleArray and TripleArray
*
* This file contains several classes for array-like access. The SingleArray
* and TripleArray classes and their typedefs to DataXYZ/... overload
* the operator[] and have a size function to act as their native arrays.
* Similar to the array classes, SingleObject represents a whole object with
* all its members in that allocated space.
*
* If an array of pointers to the elements of a TripleArray is required it can
* create a temporary class PointerArray which holds creates and deletes a
* native pointer array and follows the RAII-pattern.
*/
#ifndef DATA_TYPES_H
#define DATA_TYPES_H
/**
* Representation of a pointer to a data field with no access methods.
*
* Type-specialized access is gained by deriving from this class and
* implementing access functions like operator[] and size().
*
* The PrivateImplementation feature enables RAII-type locking mechanisms
* used in the scanserver for holding CacheObject-locks. It is protected so
* that scanserver-unaware code can only construct this class with a pointer
* and size. Initialization of a derived class with these locking mechanisms
* creates this class with the private implementation value, which will be
* deleted in this dtor when it completely falls out of scope.
*/
class DataPointer {
protected:
//! Subclass for storing further members and attaching an overloadable dtor
class PrivateImplementation {
public:
virtual ~PrivateImplementation() {}
};
public:
// DataPointer& operator=(const DataPointer&) = delete;
// DataPointer(const DataPointer&) = delete;
/**
* Ctor for the initial creation
*
* @param pointer base pointer to the data
* @param size of the pointed data in bytes
*/
DataPointer(unsigned char* pointer, unsigned int size,
PrivateImplementation* private_impl = 0) :
m_pointer(pointer), m_size(size), m_private_impl(private_impl) {
}
/**
* Copy-Ctor for passing along via return by value
*
* The type-specialized classes (B) will be called with their
* B(DataPointer&&) temporary ctor and call this constructor, so the private
* imlementation has to be taken away. The temporary inside that constructor
* isn't seen as temporary anymore, so we need a simple reference-ctor.
*/
DataPointer(DataPointer& other) {
m_pointer = other.m_pointer;
m_size = other.m_size;
// take ownership of this value, other is a temporary and will deconstruct
m_private_impl = other.m_private_impl;
other.m_private_impl = 0;
};
/**
* Same as DataPointer(DataPointer&), except this is for functions returning
* DataPointer instead of derived classes, so the temporary-ctor is used.
*/
DataPointer(DataPointer&& other) {
m_pointer = other.m_pointer;
m_size = other.m_size;
// take ownership of this value, other is a temporary and will deconstruct
m_private_impl = other.m_private_impl;
other.m_private_impl = 0;
}
//! Delete the private implementation with its derived dtor
~DataPointer() {
if(m_private_impl != 0)
delete m_private_impl;
}
//! Indicator for nullpointer / no data contained if false
inline bool valid() {
return m_size != 0;
}
inline unsigned char* get_raw_pointer() const { return m_pointer; }
protected:
unsigned char* m_pointer;
unsigned int m_size;
private:
PrivateImplementation* m_private_impl;
};
template<typename T>
class SingleArray : public DataPointer {
public:
//! Cast return-by-value temporary DataPointer to this type of array
SingleArray(DataPointer&& temp) :
DataPointer(temp)
{
}
SingleArray(SingleArray&& temp) :
DataPointer(temp)
{
}
//! Represent the pointer as an array of T
inline T& operator[](unsigned int i) const
{
return *(reinterpret_cast<T*>(m_pointer) + i);
}
//! The number of T instances in this array
unsigned int size() {
return m_size / sizeof(T);
}
};
template<typename T>
class TripleArray : public DataPointer {
public:
//! Cast return-by-value temporary DataPointer to this type of array
TripleArray(DataPointer&& temp) :
DataPointer(temp)
{
}
TripleArray(TripleArray&& temp) :
DataPointer(temp)
{
}
//! Represent the pointer as an array of T[3]
inline T* operator[](unsigned int i) const
{
return reinterpret_cast<T*>(m_pointer) + (i*3);
}
//! The number of T[3] instances in this array
unsigned int size() const {
return m_size / (3 * sizeof(T));
}
};
template<typename T>
class SingleObject : public DataPointer {
public:
//! Cast return-by-value temporary DataPointer to this type of object
SingleObject(DataPointer&& temp) :
DataPointer(temp)
{
}
SingleObject(SingleObject&& temp) :
DataPointer(temp)
{
}
//! Type-cast
inline T& get() const
{
return *reinterpret_cast<T*>(m_pointer);
}
//! There is only one object in here
unsigned int size() const {
return 1;
}
};
/**
* To simplify T** access patterns for an array of T[3] (points), this RAII-
* type class helps creating and managing this pointer array on the stack.
*/
template<typename T>
class PointerArray {
public:
//! Create a temporary array and fill it sequentially with pointers to points
PointerArray(const TripleArray<T>& data) {
unsigned int size = data.size();
m_array = new T*[size];
for(unsigned int i = 0; i < size; ++i)
m_array[i] = data[i];
}
//! Removes the temporary array on destruction (RAII)
~PointerArray() {
delete[] m_array;
}
//! Conversion operator to interface the TripleArray to a T** array
inline T** get() const { return m_array; }
private:
T** m_array;
};
// TODO: naming, see scan.h
typedef TripleArray<double> DataXYZ;
typedef TripleArray<float> DataXYZFloat;
typedef TripleArray<unsigned char> DataRGB;
typedef TripleArray<double> DataNormal;
typedef SingleArray<float> DataReflectance;
typedef SingleArray<float> DataTemperature;
typedef SingleArray<float> DataAmplitude;
typedef SingleArray<int> DataType;
typedef SingleArray<float> DataDeviation;
#endif //DATA_TYPES_H