Consider this design:
template <typename IndexOrder>
struct MatrixBase {
using ValueType = IndexOrder::ValueType;
// This struct provides the public interface
};
template <typename StorageProvider>
struct RowMajorOrder {
using ValueType = StorageProvider::ValueType;
// This struct provides functions to map 2D coordinates to 1D offset
};
template <typename StorageProvider>
struct ColMajorOrder {
using ValueType = StorageProvider::ValueType;
// This struct provides functions to map 2D coordinates to 1D offset
};
template <typename T>
struct OwnedStorage {
typedef T ValueType;
// This struct manages the allocation of a continuous block of memory
};
template <typename T>
struct BorrowedStorage {
typedef T ValueType;
// This struct stores a pointer to a block of memory managed by others
};
// The type aliases are responsible for the wrapping
template <typename T>
using MatrixRowMajor = MatrixBase<RowMajorOrder<OwnedStorage<T>>>;
template <typename T>
using MatrixColMajor = MatrixBase<ColMajorOrder<OwnedStorage<T>>>;
template <typename T>
using MatrixRowMajorView = MatrixBase<RowMajorOrder<BorrowedStorage<T>>>;
template <typename T>
using MatrixColMajorView = MatrixBase<ColMajorOrder<BorrowedStorage<T>>>;
When the user needs to use the type, they write:
MatrixRowMajor<double> my_matrix;
Instead of making T
a type parameter of MatrixBase
, this design wraps T
into nested layers of structures.
The type MatrixBase
receives the wrapped nested structures instead of T
directly. Whenever MatrixBase
needs to refer to T
, it uses the associated type ValueType
.
Lastly, the user uses the provided type aliases MatrixRowMajor
etc. The user only provides T
. Those type aliases are responsible for the wrapping.
Question: What is this design paradigm called? Do we have a name for it?
(A similar design is also used in the Rust library ndarray.)
This is called Policy Based Design