dev #2
51 changed files with 3069 additions and 510 deletions
|
@ -7,7 +7,7 @@ steps:
|
||||||
- source /opt/rh/gcc-toolset-9/enable
|
- source /opt/rh/gcc-toolset-9/enable
|
||||||
- mkdir build-gcc
|
- mkdir build-gcc
|
||||||
- cd build-gcc
|
- cd build-gcc
|
||||||
- cmake3 -DRUN_PIPELINE=on -DSCALAR_BUILD=on ..
|
- cmake3 -DSCALAR_BUILD=on ..
|
||||||
- make -j2
|
- make -j2
|
||||||
- make test
|
- make test
|
||||||
- cd ..
|
- cd ..
|
||||||
|
|
|
@ -2,27 +2,44 @@ cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
project(cnorxz)
|
project(cnorxz)
|
||||||
|
|
||||||
|
# LIB VERSION
|
||||||
|
|
||||||
|
set(VERSION_PART "pre")
|
||||||
|
set(VERSION_TAG_HASH "6857e3fc7d0af25db3a925791d1cabc6342b930a")
|
||||||
|
|
||||||
|
# OPTIONS
|
||||||
|
|
||||||
|
option(SCALAR_BUILD "" OFF)
|
||||||
|
|
||||||
|
# INCLUDES
|
||||||
|
|
||||||
include(cmake/check_avx.cmake)
|
include(cmake/check_avx.cmake)
|
||||||
|
|
||||||
|
# GIT VARIABLES
|
||||||
|
|
||||||
execute_process(COMMAND bash "-c" "git rev-parse HEAD" OUTPUT_VARIABLE GIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
execute_process(COMMAND bash "-c" "git rev-parse HEAD" OUTPUT_VARIABLE GIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
execute_process(COMMAND bash "-c" "git tag -l --sort=refname 'v*' | tail -n1" OUTPUT_VARIABLE GIT_TAG OUTPUT_STRIP_TRAILING_WHITESPACE)
|
execute_process(COMMAND bash "-c" "git rev-parse --abbrev-ref HEAD" OUTPUT_VARIABLE GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
execute_process(COMMAND bash "-c" "git rev-list -n 1 ${GIT_TAG}" OUTPUT_VARIABLE GIT_TAG_HASH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
|
# BUILD / CHECK VERSION STRING
|
||||||
|
|
||||||
message(STATUS "${GIT_HASH}")
|
message(STATUS "${GIT_HASH}")
|
||||||
option(RUN_PIPELINE "" OFF)
|
message(STATUS "${VERSION_PART}")
|
||||||
option(SCALAR_BUILD "" OFF)
|
message(STATUS "${VERSION_TAG_HASH}")
|
||||||
if(RUN_PIPELINE)
|
set(VERSION "${VERSION_PART}")
|
||||||
set(VERSION "v0.0.0-test")
|
if(NOT ("${GIT_BRANCH}" EQUAL "release"))
|
||||||
else()
|
if(NOT ("${GIT_HASH}" EQUAL "${VERSION_TAG_HASH}"))
|
||||||
message(STATUS "${GIT_TAG}")
|
|
||||||
message(STATUS "${GIT_TAG_HASH}")
|
|
||||||
string(SUBSTRING "${GIT_TAG}" 1 -1 VERSION)
|
|
||||||
if(NOT ("${GIT_HASH}" EQUAL "${GIT_TAG_HASH}"))
|
|
||||||
string(SUBSTRING ${GIT_HASH} 0 7 GIT_HASH_SHORT)
|
string(SUBSTRING ${GIT_HASH} 0 7 GIT_HASH_SHORT)
|
||||||
set(VERSION "${VERSION}-${GIT_HASH_SHORT}")
|
set(VERSION "${VERSION}-${GIT_BRANCH}-${GIT_HASH_SHORT}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if(NOT ("${GIT_HASH}" EQUAL "${VERSION_TAG_HASH}"))
|
||||||
|
message(FATAL_ERROR "version mash-up, do not use, contact maintainer")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "version = ${VERSION}")
|
message(STATUS "version = ${VERSION}")
|
||||||
|
|
||||||
|
# CHECK COMPILER
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0)
|
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0)
|
||||||
message(FATAL_ERROR "require gcc version >= 7.0")
|
message(FATAL_ERROR "require gcc version >= 7.0")
|
||||||
|
@ -31,10 +48,16 @@ else()
|
||||||
message(WARNING "compiler ${CMAKE_CXX_COMPILER_ID} officially not supported")
|
message(WARNING "compiler ${CMAKE_CXX_COMPILER_ID} officially not supported")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# FLAGS
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++17 -Wpedantic -O2 -march=native -faligned-new -funroll-loops -fopenmp")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++17 -Wpedantic -O2 -march=native -faligned-new -funroll-loops -fopenmp")
|
||||||
|
|
||||||
|
# TESTING
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
|
# INSTALL PATH
|
||||||
|
|
||||||
if(IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}")
|
if(IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}")
|
||||||
set(INSTALL_PATH ${CMAKE_INSTALL_PREFIX})
|
set(INSTALL_PATH ${CMAKE_INSTALL_PREFIX})
|
||||||
else()
|
else()
|
||||||
|
@ -43,6 +66,8 @@ else()
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "found absolute install path '${INSTALL_PATH}'")
|
message(STATUS "found absolute install path '${INSTALL_PATH}'")
|
||||||
|
|
||||||
|
# SCALAR / INTRINSICS
|
||||||
|
|
||||||
if(NOT ${SCALAR_BUILD})
|
if(NOT ${SCALAR_BUILD})
|
||||||
message(STATUS "check for intrinsics")
|
message(STATUS "check for intrinsics")
|
||||||
check_avx()
|
check_avx()
|
||||||
|
@ -55,6 +80,8 @@ if(NOT ${SCALAR_BUILD})
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# CHECK LIBRARIES : GTest
|
||||||
|
|
||||||
message(STATUS "check for libraries")
|
message(STATUS "check for libraries")
|
||||||
find_package( GTest REQUIRED )
|
find_package( GTest REQUIRED )
|
||||||
if(GTest_FOUND)
|
if(GTest_FOUND)
|
||||||
|
@ -63,6 +90,8 @@ else()
|
||||||
message(FATAL_ERROR "GTest not found")
|
message(FATAL_ERROR "GTest not found")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# CHECK LIBRARIES : Threads
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
if(Threads_FOUND)
|
if(Threads_FOUND)
|
||||||
#include_directories(${Threads_INCLUDE_DIRS})
|
#include_directories(${Threads_INCLUDE_DIRS})
|
||||||
|
@ -70,12 +99,16 @@ else()
|
||||||
message(FATAL_ERROR "Threads not found")
|
message(FATAL_ERROR "Threads not found")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# CHECK LIBRARIES : hdf5
|
||||||
|
|
||||||
if(DEFINED ENABLE_hdf5)
|
if(DEFINED ENABLE_hdf5)
|
||||||
set(ENABLE_hdf5 ${ENABLE_hdf5} CACHE BOOL "enable hdf5")
|
set(ENABLE_hdf5 ${ENABLE_hdf5} CACHE BOOL "enable hdf5")
|
||||||
else()
|
else()
|
||||||
set(ENABLE_hdf5 TRUE CACHE BOOL "enable hdf5")
|
set(ENABLE_hdf5 TRUE CACHE BOOL "enable hdf5")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# CHECK LIBRARIES : cereal
|
||||||
|
|
||||||
if(DEFINED ENABLE_cereal)
|
if(DEFINED ENABLE_cereal)
|
||||||
set(ENABLE_cereal ${ENABLE_cereal} CACHE BOOL "enable hdf5")
|
set(ENABLE_cereal ${ENABLE_cereal} CACHE BOOL "enable hdf5")
|
||||||
else()
|
else()
|
||||||
|
@ -96,8 +129,12 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# DEFINES
|
||||||
|
|
||||||
add_definitions(-DVERSION="${VERSION}")
|
add_definitions(-DVERSION="${VERSION}")
|
||||||
add_definitions(-DGIT_COMMIT="${GIT_HASH}")
|
add_definitions(-DGIT_COMMIT="${GIT_HASH}")
|
||||||
add_definitions(-DCXX_FLAGS="${CMAKE_CXX_FLAGS}")
|
add_definitions(-DCXX_FLAGS="${CMAKE_CXX_FLAGS}")
|
||||||
|
|
||||||
|
# CONTINUE WITH SUB-DIRECTORIES
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
|
@ -36,9 +36,9 @@ The tools of the library are accessible within the namespace `CNORXZ`.
|
||||||
|
|
||||||
### Basics and Library organization
|
### Basics and Library organization
|
||||||
|
|
||||||
This library consists of several building blocks. For simple usage, the most important building blocks are [ranges](#ranges), [indices](#indices) and [array types](#arrays).
|
This library consists of several building blocks. For simple usage, the most important building blocks are [ranges](#sec-ranges), [indices](#sec-indices) and [arrays](#sec-array-types).
|
||||||
|
|
||||||
#### Ranges
|
#### Ranges {#sec-ranges}
|
||||||
|
|
||||||
Basically, a *range* defines a meta data space. There are several range class types, which are derived from the abstract base class `RangeBase`. Ranges can only be created by the corresponding factory and exclusively exist within a shared pointer; they cannot be copied. Available range class types are:
|
Basically, a *range* defines a meta data space. There are several range class types, which are derived from the abstract base class `RangeBase`. Ranges can only be created by the corresponding factory and exclusively exist within a shared pointer; they cannot be copied. Available range class types are:
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ Basically, a *range* defines a meta data space. There are several range class ty
|
||||||
|
|
||||||
* `YRange` : The same as `MRange` but the number of ranges and their types can be specified at runtime.
|
* `YRange` : The same as `MRange` but the number of ranges and their types can be specified at runtime.
|
||||||
|
|
||||||
#### Indices
|
#### Indices {#sec-indices}
|
||||||
|
|
||||||
For each range type there is a corresponding index type (`CIndex`, `UIndex<MetaT>`, `SIndex<MetaT,S>`, `PIndex<IndexT>`, `MIndex<IndexTs...>`, `YIndex`). They act as const iterators on the ranges and are a crucial component to define operations on containers. In contrast to the ranges, all index types must be known at compile time (static polymorphism, `IndexInterface<Index,MetaT>`).
|
For each range type there is a corresponding index type (`CIndex`, `UIndex<MetaT>`, `SIndex<MetaT,S>`, `PIndex<IndexT>`, `MIndex<IndexTs...>`, `YIndex`). They act as const iterators on the ranges and are a crucial component to define operations on containers. In contrast to the ranges, all index types must be known at compile time (static polymorphism, `IndexInterface<Index,MetaT>`).
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ Apart from range specific indices, there exist also special indices:
|
||||||
|
|
||||||
* `BIndex<T>` : The same as `AIndex`, but not const.
|
* `BIndex<T>` : The same as `AIndex`, but not const.
|
||||||
|
|
||||||
#### Array types
|
#### Array types {#sec-array-types}
|
||||||
|
|
||||||
Finally, there are the container classes (arrays), which are derived from `CArrayBase<T>` (const) or `ArrayBase<T>` for a given data type `T`. All arrays are defined on a range, their data can be accessed or iterated over using suitable indices. The array-type actually containing data is called `MArray<T>`. Moreover, there exist array-types that do not contain data, but view the data of other arrays or at least parts of the data. These are called `CSlice<T>` (const view) or `Slice`.
|
Finally, there are the container classes (arrays), which are derived from `CArrayBase<T>` (const) or `ArrayBase<T>` for a given data type `T`. All arrays are defined on a range, their data can be accessed or iterated over using suitable indices. The array-type actually containing data is called `MArray<T>`. Moreover, there exist array-types that do not contain data, but view the data of other arrays or at least parts of the data. These are called `CSlice<T>` (const view) or `Slice`.
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,16 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "[";
|
ss << "[";
|
||||||
auto it = a.begin();
|
if(a.size() == 0){
|
||||||
for(; it != a.end()-1; ++it){
|
ss << "]";
|
||||||
ss << toString(*it) << ",";
|
}
|
||||||
|
else {
|
||||||
|
auto it = a.begin();
|
||||||
|
for(; it != a.end()-1; ++it){
|
||||||
|
ss << toString(*it) << ",";
|
||||||
|
}
|
||||||
|
ss << toString(*it) << "]";
|
||||||
}
|
}
|
||||||
ss << toString(*it) << "]";
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,11 +51,16 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "(";
|
ss << "(";
|
||||||
auto it = a.begin();
|
if constexpr(N == 0){
|
||||||
for(; it != a.end()-1; ++it){
|
ss << ")";
|
||||||
ss << toString(*it) << ",";
|
}
|
||||||
|
else {
|
||||||
|
auto it = a.begin();
|
||||||
|
for(; it != a.end()-1; ++it){
|
||||||
|
ss << toString(*it) << ",";
|
||||||
|
}
|
||||||
|
ss << toString(*it) << ")";
|
||||||
}
|
}
|
||||||
ss << toString(*it) << ")";
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +83,26 @@ namespace CNORXZ
|
||||||
return String("(") + toString(p.first) + "," + toString(p.second) + ")";
|
return String("(") + toString(p.first) + "," + toString(p.second) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
String ToString<std::map<T,S>>::func(const std::map<T,S>& p)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "{";
|
||||||
|
if(p.size() == 0){
|
||||||
|
ss << "}";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto it = p.begin();
|
||||||
|
auto e = p.end();
|
||||||
|
e--;
|
||||||
|
for(; it != e; ++it){
|
||||||
|
ss << toString(it->first) << ":" << toString(it->second) << ",";
|
||||||
|
}
|
||||||
|
ss << toString(it->first) << ":" << toString(it->second) << "}";
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
String toString(const T& a)
|
String toString(const T& a)
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,6 +97,20 @@ namespace CNORXZ
|
||||||
static String func(const std::pair<T,S>& t);
|
static String func(const std::pair<T,S>& t);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ***
|
||||||
|
Specialization of ToString for maps
|
||||||
|
@tparam T key type
|
||||||
|
@tparam S value type
|
||||||
|
*/
|
||||||
|
template <typename T, typename S>
|
||||||
|
struct ToString<std::map<T,S>>
|
||||||
|
{
|
||||||
|
/** cast to string
|
||||||
|
@param a map to be casted
|
||||||
|
*/
|
||||||
|
static String func(const std::map<T,S>& t);
|
||||||
|
};
|
||||||
|
|
||||||
/** ***
|
/** ***
|
||||||
Specialization of ToString for DType
|
Specialization of ToString for DType
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
This file contains the declaration of all library types
|
This file contains the declaration of all library types
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -28,9 +28,9 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
/**********************
|
/*====================+
|
||||||
* standard types *
|
| standard types |
|
||||||
**********************/
|
=====================*/
|
||||||
|
|
||||||
typedef std::intptr_t PtrId;
|
typedef std::intptr_t PtrId;
|
||||||
typedef int32_t Int;
|
typedef int32_t Int;
|
||||||
|
@ -80,9 +80,9 @@ namespace CNORXZ
|
||||||
template <SizeT N>
|
template <SizeT N>
|
||||||
using CSizeT = std::integral_constant<SizeT,N>;
|
using CSizeT = std::integral_constant<SizeT,N>;
|
||||||
|
|
||||||
/*********************
|
/*===================+
|
||||||
* library types *
|
| library types |
|
||||||
*********************/
|
+===================*/
|
||||||
|
|
||||||
/***
|
/***
|
||||||
Naming Prefixes:
|
Naming Prefixes:
|
||||||
|
@ -302,9 +302,9 @@ namespace CNORXZ
|
||||||
template <class CXpr>
|
template <class CXpr>
|
||||||
class Contraction;
|
class Contraction;
|
||||||
|
|
||||||
/*********************
|
/*===================+
|
||||||
* derived types *
|
| derived types |
|
||||||
*********************/
|
+===================*/
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using Vector = std::vector<T,Allocator<T>>;
|
using Vector = std::vector<T,Allocator<T>>;
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
|
||||||
/**********************
|
/*====================+
|
||||||
* COpInterface *
|
| COpInterface |
|
||||||
**********************/
|
+====================*/
|
||||||
|
|
||||||
template <class OpT>
|
template <class OpT>
|
||||||
template <class F, class IndexT>
|
template <class F, class IndexT>
|
||||||
|
@ -37,9 +37,9 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************
|
/*===================+
|
||||||
* OpInterface *
|
| OpInterface |
|
||||||
*********************/
|
+===================*/
|
||||||
|
|
||||||
template <class OpT>
|
template <class OpT>
|
||||||
template <class IndexT, class F, class... Args>
|
template <class IndexT, class F, class... Args>
|
||||||
|
@ -56,9 +56,9 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************
|
/*=============+
|
||||||
* COpRoot *
|
| COpRoot |
|
||||||
***************/
|
+=============*/
|
||||||
|
|
||||||
template <typename T, class IndexT>
|
template <typename T, class IndexT>
|
||||||
constexpr COpRoot<T,IndexT>::COpRoot(const CArrayBase<T>& a, const Sptr<IndexT>& ind) :
|
constexpr COpRoot<T,IndexT>::COpRoot(const CArrayBase<T>& a, const Sptr<IndexT>& ind) :
|
||||||
|
@ -123,9 +123,52 @@ namespace CNORXZ
|
||||||
return COpRoot<T,IndexT>(a, ind);
|
return COpRoot<T,IndexT>(a, ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************
|
/*=============+
|
||||||
* OpCont *
|
| POpRoot |
|
||||||
****************/
|
+=============*/
|
||||||
|
|
||||||
|
template <class IndexT, class Op>
|
||||||
|
constexpr POpRoot<IndexT,Op>::POpRoot(const Sptr<IndexT>& ind, const SizeT* parts, Op&& op) :
|
||||||
|
mIndex(ind),
|
||||||
|
mFp(1,parts),
|
||||||
|
mOp(std::forward<Op>(op))
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <class IndexT, class Op>
|
||||||
|
template <class PosT>
|
||||||
|
constexpr decltype(auto) POpRoot<IndexT,Op>::operator()(const PosT& pos) const
|
||||||
|
{
|
||||||
|
return mOp(mFp(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class IndexT, class Op>
|
||||||
|
constexpr decltype(auto) POpRoot<IndexT,Op>::operator()() const
|
||||||
|
{
|
||||||
|
return mOp(mFp(SPos<0>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class IndexT, class Op>
|
||||||
|
template <SizeT I>
|
||||||
|
constexpr decltype(auto) POpRoot<IndexT,Op>::rootSteps(const IndexId<I>& id) const
|
||||||
|
{
|
||||||
|
return mIndex->stepSize(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class IndexT, class Op>
|
||||||
|
constexpr decltype(auto) POpRoot<IndexT,Op>::data() const
|
||||||
|
{
|
||||||
|
return mOp->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class IndexT, class Op>
|
||||||
|
constexpr decltype(auto) poproot(const Sptr<IndexT>& ind, const SizeT* parts, Op&& op)
|
||||||
|
{
|
||||||
|
return POpRoot(ind, parts, std::forward<Op>(op));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==============+
|
||||||
|
| OpCont |
|
||||||
|
+==============*/
|
||||||
|
|
||||||
template <typename T, class IndexT>
|
template <typename T, class IndexT>
|
||||||
constexpr OpCont<T,IndexT>::OpCont(const Sptr<IndexT>& ind) :
|
constexpr OpCont<T,IndexT>::OpCont(const Sptr<IndexT>& ind) :
|
||||||
|
@ -236,9 +279,9 @@ namespace CNORXZ
|
||||||
return mC.data();
|
return mC.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************
|
/*==============+
|
||||||
* OpRoot *
|
| OpRoot |
|
||||||
****************/
|
+==============*/
|
||||||
|
|
||||||
template <typename T, class IndexT>
|
template <typename T, class IndexT>
|
||||||
constexpr OpRoot<T,IndexT>::OpRoot(ArrayBase<T>& a, const Sptr<IndexT>& ind) :
|
constexpr OpRoot<T,IndexT>::OpRoot(ArrayBase<T>& a, const Sptr<IndexT>& ind) :
|
||||||
|
@ -327,9 +370,9 @@ namespace CNORXZ
|
||||||
return OpRoot<T,IndexT>(a, ind);
|
return OpRoot<T,IndexT>(a, ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************
|
/*=================+
|
||||||
* Operation *
|
| Operation |
|
||||||
*******************/
|
+=================*/
|
||||||
|
|
||||||
template <class F, class... Ops>
|
template <class F, class... Ops>
|
||||||
constexpr Operation<F,Ops...>::Operation(F&& f, const Ops&... ops) :
|
constexpr Operation<F,Ops...>::Operation(F&& f, const Ops&... ops) :
|
||||||
|
@ -411,9 +454,9 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************
|
/*===================+
|
||||||
* Contraction *
|
| Contraction |
|
||||||
*********************/
|
+===================*/
|
||||||
|
|
||||||
template <class CXpr>
|
template <class CXpr>
|
||||||
constexpr Contraction<CXpr>::Contraction(CXpr&& cxpr) :
|
constexpr Contraction<CXpr>::Contraction(CXpr&& cxpr) :
|
||||||
|
@ -447,9 +490,9 @@ namespace CNORXZ
|
||||||
return Contraction<CXprT>( i->ifor( op, f ) );
|
return Contraction<CXprT>( i->ifor( op, f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************
|
/*======================+
|
||||||
* various functions *
|
| various functions |
|
||||||
************************/
|
+======================*/
|
||||||
|
|
||||||
template <class IndexT>
|
template <class IndexT>
|
||||||
constexpr decltype(auto) indexOp(const Sptr<IndexT>& i)
|
constexpr decltype(auto) indexOp(const Sptr<IndexT>& i)
|
||||||
|
|
|
@ -97,6 +97,36 @@ namespace CNORXZ
|
||||||
template <typename T, class IndexT>
|
template <typename T, class IndexT>
|
||||||
constexpr decltype(auto) coproot(const T* a, const Sptr<IndexT>& ind);
|
constexpr decltype(auto) coproot(const T* a, const Sptr<IndexT>& ind);
|
||||||
|
|
||||||
|
template <class IndexT, class Op>
|
||||||
|
class POpRoot : public COpInterface<POpRoot<IndexT,Op>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef COpInterface<POpRoot<IndexT,Op>> OI;
|
||||||
|
|
||||||
|
constexpr POpRoot() = default;
|
||||||
|
|
||||||
|
constexpr POpRoot(const Sptr<IndexT>& ind, const SizeT* parts, Op&& op);
|
||||||
|
|
||||||
|
template <class PosT>
|
||||||
|
constexpr decltype(auto) operator()(const PosT& pos) const;
|
||||||
|
|
||||||
|
constexpr decltype(auto) operator()() const;
|
||||||
|
|
||||||
|
template <SizeT I>
|
||||||
|
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
|
||||||
|
|
||||||
|
constexpr decltype(auto) data() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Sptr<IndexT> mIndex;
|
||||||
|
FPos mFp;
|
||||||
|
Op mOp;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class IndexT, class Op>
|
||||||
|
constexpr decltype(auto) poproot(const Sptr<IndexT>& ind, const SizeT* parts, Op&& op);
|
||||||
|
|
||||||
template <typename T, class IndexT>
|
template <typename T, class IndexT>
|
||||||
class OpCont : public OpInterface<OpCont<T,IndexT>>
|
class OpCont : public OpInterface<OpCont<T,IndexT>>
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/crange.h
|
@file include/ranges/crange.h
|
||||||
@brief ...
|
@brief CRange and CIndex declaration.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -35,8 +34,8 @@ namespace CNORXZ
|
||||||
DEFAULT_MEMBERS(CIndex); /**< default constructors and assignments */
|
DEFAULT_MEMBERS(CIndex); /**< default constructors and assignments */
|
||||||
|
|
||||||
/** Construct index from range and position.
|
/** Construct index from range and position.
|
||||||
@param range Range to iterate over
|
@param range Range to iterate over.
|
||||||
@param pos lexicographic position
|
@param pos lexicographic position.
|
||||||
*/
|
*/
|
||||||
CIndex(const RangePtr& range, SizeT pos = 0);
|
CIndex(const RangePtr& range, SizeT pos = 0);
|
||||||
|
|
||||||
|
@ -80,7 +79,7 @@ namespace CNORXZ
|
||||||
SizeT operator*() const;
|
SizeT operator*() const;
|
||||||
|
|
||||||
/** @copydoc IndexInterface::dim() */
|
/** @copydoc IndexInterface::dim() */
|
||||||
SizeT dim() const; // = 1
|
SizeT dim() const;
|
||||||
|
|
||||||
/** @copydoc IndexInterface::range() */
|
/** @copydoc IndexInterface::range() */
|
||||||
Sptr<RangeType> range() const;
|
Sptr<RangeType> range() const;
|
||||||
|
@ -124,30 +123,29 @@ namespace CNORXZ
|
||||||
Sptr<RangeType> mRangePtr;
|
Sptr<RangeType> mRangePtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** make index pack of a CIndex and another index
|
/** Make index pack of a CIndex and another index.
|
||||||
@tparam type of the second index
|
@param a pointer to CIndex.
|
||||||
@param a pointer to CIndex
|
@param b pointer to another index.
|
||||||
@param b pointer to another index
|
|
||||||
*/
|
*/
|
||||||
template <class I>
|
template <class I>
|
||||||
decltype(auto) operator*(const Sptr<CIndex>& a, const Sptr<I>& b);
|
decltype(auto) operator*(const Sptr<CIndex>& a, const Sptr<I>& b);
|
||||||
|
|
||||||
/** ****
|
/** ****
|
||||||
specific factory for CRange
|
Specific factory for CRange.
|
||||||
*/
|
*/
|
||||||
class CRangeFactory : public RangeFactoryBase
|
class CRangeFactory : public RangeFactoryBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef CRange oType;
|
typedef CRange oType;
|
||||||
|
|
||||||
/** construct and setup factory
|
/** Construct and setup factory.
|
||||||
@param size size of the range to be constructed
|
@param size Size of the range to be constructed.
|
||||||
*/
|
*/
|
||||||
CRangeFactory(SizeT size);
|
CRangeFactory(SizeT size);
|
||||||
|
|
||||||
/** construct and setup factory
|
/** Construct and setup factory.
|
||||||
@param size size of the range to be constructed
|
@param size Size of the range to be constructed.
|
||||||
@param ref range the range to be constructed is related to
|
@param ref Range the range to be constructed is related to.
|
||||||
*/
|
*/
|
||||||
CRangeFactory(SizeT size, RangePtr ref);
|
CRangeFactory(SizeT size, RangePtr ref);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
@brief ...
|
@brief ...
|
||||||
|
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -40,6 +40,12 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class I>
|
||||||
|
decltype(auto) operator*(const Sptr<DIndex>& a, const Sptr<I>& b)
|
||||||
|
{
|
||||||
|
return iptrMul(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
template <class I>
|
template <class I>
|
||||||
I indexAs(const DIndex& i)
|
I indexAs(const DIndex& i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/dindex.h
|
@file include/ranges/dindex.h
|
||||||
@brief ...
|
@brief DIndex declaration
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -154,6 +153,13 @@ namespace CNORXZ
|
||||||
XIndexPtr mI;
|
XIndexPtr mI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Make index pack of a DIndex and another index.
|
||||||
|
@param a pointer to DIndex.
|
||||||
|
@param b pointer to another index.
|
||||||
|
*/
|
||||||
|
template <class I>
|
||||||
|
decltype(auto) operator*(const Sptr<DIndex>& a, const Sptr<I>& b);
|
||||||
|
|
||||||
/** Trait-specialization:
|
/** Trait-specialization:
|
||||||
DIndex can have sub-indices
|
DIndex can have sub-indices
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
@brief ...
|
@brief ...
|
||||||
|
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -20,7 +20,17 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
/** *****
|
||||||
|
Extension Index
|
||||||
|
|
||||||
|
Elements accessed through this index in a loop
|
||||||
|
are treated and processed through a single access
|
||||||
|
allowing the usage of vector extensions
|
||||||
|
|
||||||
|
@tparam MetaT Index meta data type
|
||||||
|
@tparam S Vector size
|
||||||
|
@tparam L Static index label
|
||||||
|
*/
|
||||||
template <typename MetaT, SizeT S, SizeT L>
|
template <typename MetaT, SizeT S, SizeT L>
|
||||||
class EIndex : public LIndex<SIndex<MetaT,S>,L>
|
class EIndex : public LIndex<SIndex<MetaT,S>,L>
|
||||||
{
|
{
|
||||||
|
@ -28,9 +38,15 @@ namespace CNORXZ
|
||||||
typedef typename LIndex<SIndex<MetaT,S>,L>::IB IB;
|
typedef typename LIndex<SIndex<MetaT,S>,L>::IB IB;
|
||||||
typedef typename LIndex<SIndex<MetaT,S>,L>::RangeType RangeType;
|
typedef typename LIndex<SIndex<MetaT,S>,L>::RangeType RangeType;
|
||||||
|
|
||||||
DEFAULT_MEMBERS(EIndex);
|
DEFAULT_MEMBERS(EIndex); /**< default constructors and assignments */
|
||||||
EIndex(const Sptr<LIndex<SIndex<MetaT,S>,L>>& i);
|
EIndex(const Sptr<LIndex<SIndex<MetaT,S>,L>>& i);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::ifor()
|
||||||
|
|
||||||
|
Specialization for EIndex: access all elements
|
||||||
|
at once, allowing usage of vector extensions
|
||||||
|
@see EFor
|
||||||
|
*/
|
||||||
template <class Xpr, class F>
|
template <class Xpr, class F>
|
||||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||||
|
|
||||||
|
@ -38,6 +54,10 @@ namespace CNORXZ
|
||||||
Sptr<LIndex<SIndex<MetaT,S>,L>> mLI;
|
Sptr<LIndex<SIndex<MetaT,S>,L>> mLI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ***
|
||||||
|
EIndex is an index
|
||||||
|
@see is_index
|
||||||
|
*/
|
||||||
template <typename MetaT, SizeT S, SizeT L>
|
template <typename MetaT, SizeT S, SizeT L>
|
||||||
struct is_index<EIndex<MetaT,S,L>>
|
struct is_index<EIndex<MetaT,S,L>>
|
||||||
{
|
{
|
||||||
|
@ -54,24 +74,51 @@ namespace CNORXZ
|
||||||
static constexpr bool value = true;
|
static constexpr bool value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Make index pack from EIndex and second index of arbitrary type
|
||||||
|
*/
|
||||||
template <typename MetaT, SizeT S, SizeT L, class I1>
|
template <typename MetaT, SizeT S, SizeT L, class I1>
|
||||||
decltype(auto) operator*(const Sptr<EIndex<MetaT,S,L>>& a, const Sptr<I1>& b);
|
decltype(auto) operator*(const Sptr<EIndex<MetaT,S,L>>& a, const Sptr<I1>& b);
|
||||||
|
|
||||||
|
/** Create Eindex pointer from LIndex pointer
|
||||||
|
*/
|
||||||
template <typename MetaT, SizeT S, SizeT L>
|
template <typename MetaT, SizeT S, SizeT L>
|
||||||
decltype(auto) eindexPtr(const Sptr<LIndex<SIndex<MetaT,S>,L>>& i);
|
decltype(auto) eindexPtr(const Sptr<LIndex<SIndex<MetaT,S>,L>>& i);
|
||||||
|
|
||||||
|
/** Create Eindex pointer from SIndex pointer
|
||||||
|
@tparam L Static index label
|
||||||
|
*/
|
||||||
template <SizeT L, typename MetaT, SizeT S>
|
template <SizeT L, typename MetaT, SizeT S>
|
||||||
decltype(auto) eindexPtr(const Sptr<SIndex<MetaT,S>>& i);
|
decltype(auto) eindexPtr(const Sptr<SIndex<MetaT,S>>& i);
|
||||||
|
|
||||||
|
/** Create Eindex pointer from LIndex pointer
|
||||||
|
@param l Static index label
|
||||||
|
*/
|
||||||
template <typename MetaT, SizeT S, SizeT L>
|
template <typename MetaT, SizeT S, SizeT L>
|
||||||
decltype(auto) eindexPtr(const Sptr<SIndex<MetaT,S>>& i, CSizeT<L> l);
|
decltype(auto) eindexPtr(const Sptr<SIndex<MetaT,S>>& i, CSizeT<L> l);
|
||||||
|
|
||||||
|
/** Split given index into pack of EIndex and remainder index
|
||||||
|
@param i Index to be split
|
||||||
|
@tparam S Vector size
|
||||||
|
@tparam L1 label of EIndex
|
||||||
|
@tparam L2 label of remainder index
|
||||||
|
*/
|
||||||
template <SizeT S, SizeT L1, SizeT L2, class Index>
|
template <SizeT S, SizeT L1, SizeT L2, class Index>
|
||||||
decltype(auto) eplex(const Sptr<Index>& i);
|
decltype(auto) eplex(const Sptr<Index>& i);
|
||||||
|
|
||||||
|
/** Split given index into pack of EIndex and remainder index
|
||||||
|
@param i Index to be split
|
||||||
|
@param s Vector size
|
||||||
|
@param l label of EIndex
|
||||||
|
*/
|
||||||
template <class Index, SizeT S, SizeT L>
|
template <class Index, SizeT S, SizeT L>
|
||||||
decltype(auto) eplex(const Sptr<Index>& i, CSizeT<S> s, CSizeT<L> l);
|
decltype(auto) eplex(const Sptr<Index>& i, CSizeT<S> s, CSizeT<L> l);
|
||||||
|
|
||||||
|
/** Split given index into pack of EIndex and remainder index
|
||||||
|
@param i Index to be split
|
||||||
|
@param s Vector size
|
||||||
|
@param l1 label of EIndex
|
||||||
|
@param l2 label of remainder index
|
||||||
|
*/
|
||||||
template <class Index, SizeT S, SizeT L1, SizeT L2>
|
template <class Index, SizeT S, SizeT L1, SizeT L2>
|
||||||
decltype(auto) eplex(const Sptr<Index>& i, CSizeT<S> s, CSizeT<L1> l1, CSizeT<L2> l2);
|
decltype(auto) eplex(const Sptr<Index>& i, CSizeT<S> s, CSizeT<L1> l1, CSizeT<L2> l2);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
@brief ...
|
@brief ...
|
||||||
|
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -18,26 +18,51 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
/** ****
|
||||||
|
Type trait: Check if format has static size.
|
||||||
|
*/
|
||||||
template <class FormatT> struct is_static_format { CXZ_CVAL_FALSE; };
|
template <class FormatT> struct is_static_format { CXZ_CVAL_FALSE; };
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Multi index format of static size.
|
||||||
|
Wrapper of standard array of UPos.
|
||||||
|
@tparam N Format size
|
||||||
|
*/
|
||||||
template <SizeT N>
|
template <SizeT N>
|
||||||
class MFormat
|
class MFormat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Arr<UPos,N> InputType;
|
typedef Arr<UPos,N> InputType;
|
||||||
|
|
||||||
SP_DEFAULT_MEMBERS(constexpr,MFormat);
|
SP_DEFAULT_MEMBERS(constexpr,MFormat); /**< default constructors and assignments */
|
||||||
|
|
||||||
|
/** Construct MFormat from standard array.
|
||||||
|
@param b Input array
|
||||||
|
*/
|
||||||
explicit constexpr MFormat(const Arr<UPos,N>& b);
|
explicit constexpr MFormat(const Arr<UPos,N>& b);
|
||||||
|
|
||||||
|
/** Construct MFormat from format of arbitrary type.
|
||||||
|
The input format size has to match the static size N.
|
||||||
|
@param f Input format
|
||||||
|
*/
|
||||||
template <class FormatT>
|
template <class FormatT>
|
||||||
constexpr MFormat(const FormatT& f);
|
constexpr MFormat(const FormatT& f);
|
||||||
|
|
||||||
|
/** Get underlying array. */
|
||||||
const Arr<UPos,N>& all() const;
|
const Arr<UPos,N>& all() const;
|
||||||
|
|
||||||
|
/** Get format size. */
|
||||||
constexpr decltype(auto) size() const;
|
constexpr decltype(auto) size() const;
|
||||||
|
|
||||||
|
/** Get format element.
|
||||||
|
@param i CSizeT indicating static element position
|
||||||
|
*/
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
constexpr decltype(auto) get(CSizeT<I> i) const;
|
constexpr decltype(auto) get(CSizeT<I> i) const;
|
||||||
|
|
||||||
|
/** Get format element.
|
||||||
|
@param i CSizeT indicating static element position
|
||||||
|
*/
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
constexpr decltype(auto) operator[](CSizeT<I> i) const;
|
constexpr decltype(auto) operator[](CSizeT<I> i) const;
|
||||||
|
|
||||||
|
@ -46,27 +71,58 @@ namespace CNORXZ
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
MFormat has static size.
|
||||||
|
@see is_static_format
|
||||||
|
*/
|
||||||
template <SizeT N> struct is_static_format<MFormat<N>> { CXZ_CVAL_TRUE; };
|
template <SizeT N> struct is_static_format<MFormat<N>> { CXZ_CVAL_TRUE; };
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Multi index format of static size.
|
||||||
|
Wrapper of standard tuple of position types.
|
||||||
|
@tparam PosT Position types.
|
||||||
|
*/
|
||||||
template <class... PosT>
|
template <class... PosT>
|
||||||
class GMFormat
|
class GMFormat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Tuple<PosT...> InputType;
|
typedef Tuple<PosT...> InputType;
|
||||||
|
|
||||||
SP_DEFAULT_MEMBERS(constexpr,GMFormat);
|
SP_DEFAULT_MEMBERS(constexpr,GMFormat); /**< default constructors and assignments */
|
||||||
|
|
||||||
|
/** Construct from tuple.
|
||||||
|
@param b Input tuple.
|
||||||
|
*/
|
||||||
explicit constexpr GMFormat(const Tuple<PosT...>& b);
|
explicit constexpr GMFormat(const Tuple<PosT...>& b);
|
||||||
|
|
||||||
|
/** Construct from tuple (move).
|
||||||
|
@param b Input tuple.
|
||||||
|
*/
|
||||||
explicit constexpr GMFormat(Tuple<PosT...>&& b);
|
explicit constexpr GMFormat(Tuple<PosT...>&& b);
|
||||||
|
|
||||||
|
/** Construct MFormat from format of arbitrary type.
|
||||||
|
The input format size has to match the number of entries
|
||||||
|
and the input entries have to be compatible with the position types.
|
||||||
|
@param f Input format
|
||||||
|
*/
|
||||||
template <class FormatT>
|
template <class FormatT>
|
||||||
constexpr GMFormat(const FormatT& f);
|
constexpr GMFormat(const FormatT& f);
|
||||||
|
|
||||||
|
/** Get underlying tuple. */
|
||||||
const Tuple<PosT...>& all() const;
|
const Tuple<PosT...>& all() const;
|
||||||
|
|
||||||
|
/** Get format size. */
|
||||||
constexpr decltype(auto) size() const;
|
constexpr decltype(auto) size() const;
|
||||||
|
|
||||||
|
/** Get format element.
|
||||||
|
@param i CSizeT indicating static element position
|
||||||
|
*/
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
constexpr decltype(auto) get(CSizeT<I> i) const;
|
constexpr decltype(auto) get(CSizeT<I> i) const;
|
||||||
|
|
||||||
|
/** Get format element.
|
||||||
|
@param i CSizeT indicating static element position
|
||||||
|
*/
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
constexpr decltype(auto) operator[](CSizeT<I> i) const;
|
constexpr decltype(auto) operator[](CSizeT<I> i) const;
|
||||||
|
|
||||||
|
@ -74,38 +130,76 @@ namespace CNORXZ
|
||||||
Tuple<PosT...> mB;
|
Tuple<PosT...> mB;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Create GMFormat from position types.
|
||||||
|
@param ps Position types.
|
||||||
|
*/
|
||||||
template <class... PosT>
|
template <class... PosT>
|
||||||
constexpr decltype(auto) gmformat(const PosT&... ps);
|
constexpr decltype(auto) gmformat(const PosT&... ps);
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
GMFormat has static size.
|
||||||
|
@see is_static_format
|
||||||
|
*/
|
||||||
template <class... PosT> struct is_static_format<GMFormat<PosT...>> { CXZ_CVAL_TRUE; };
|
template <class... PosT> struct is_static_format<GMFormat<PosT...>> { CXZ_CVAL_TRUE; };
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Multi index format of variable size
|
||||||
|
Wrapper of standard vector of UPos.
|
||||||
|
*/
|
||||||
class YFormat
|
class YFormat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Vector<UPos> InputType;
|
typedef Vector<UPos> InputType;
|
||||||
|
|
||||||
DEFAULT_MEMBERS(YFormat);
|
DEFAULT_MEMBERS(YFormat); /**< default constructors and assignments */
|
||||||
|
|
||||||
|
/** Construct from vector.
|
||||||
|
@param b Input vector.
|
||||||
|
*/
|
||||||
explicit YFormat(const Vector<UPos>& b);
|
explicit YFormat(const Vector<UPos>& b);
|
||||||
|
|
||||||
|
/** Construct from format of arbitrary type.
|
||||||
|
@param f Input format.
|
||||||
|
*/
|
||||||
template <class FormatT>
|
template <class FormatT>
|
||||||
YFormat(const FormatT& f);
|
YFormat(const FormatT& f);
|
||||||
|
|
||||||
|
/** Get underlying vector. */
|
||||||
const Vector<UPos>& all() const;
|
const Vector<UPos>& all() const;
|
||||||
|
|
||||||
|
/** Get format size. */
|
||||||
SizeT size() const;
|
SizeT size() const;
|
||||||
|
|
||||||
|
/** Get format element.
|
||||||
|
@param i CSizeT indicating static element position
|
||||||
|
*/
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
const UPos& get(CSizeT<I> i) const;
|
const UPos& get(CSizeT<I> i) const;
|
||||||
|
|
||||||
|
/** Get format element.
|
||||||
|
@param i CSizeT indicating static element position
|
||||||
|
*/
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
const UPos& operator[](CSizeT<I> i) const;
|
const UPos& operator[](CSizeT<I> i) const;
|
||||||
|
|
||||||
|
/** Get format element.
|
||||||
|
@param i E element position
|
||||||
|
*/
|
||||||
const UPos& get(SizeT i) const;
|
const UPos& get(SizeT i) const;
|
||||||
|
|
||||||
|
/** Get format element.
|
||||||
|
@param i E element position
|
||||||
|
*/
|
||||||
const UPos& operator[](SizeT i) const;
|
const UPos& operator[](SizeT i) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<UPos> mB;
|
Vector<UPos> mB;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Check if format is trivial, i.e. f[i-1] = f[i]*s[i].
|
||||||
|
@param f Vector representing the index format.
|
||||||
|
@param s Vector representing the sub-index maxima.
|
||||||
|
*/
|
||||||
bool formatIsTrivial(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
bool formatIsTrivial(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/index_mul.h
|
@file include/ranges/index_mul.h
|
||||||
@brief ...
|
@brief Index multiplication
|
||||||
|
|
||||||
|
Indices can be multiplied yielding index packs.
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -35,30 +36,71 @@ namespace CNORXZ
|
||||||
Isq<Is...> is, Isq<Js...> js);
|
Isq<Is...> is, Isq<Js...> js);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Combine two indices to a static index 2-pack.
|
||||||
|
@param a First index.
|
||||||
|
@param b Second index.
|
||||||
|
@return Static index 2-pack
|
||||||
|
*/
|
||||||
template <class I1, typename Meta1, class I2, typename Meta2>
|
template <class I1, typename Meta1, class I2, typename Meta2>
|
||||||
inline decltype(auto) operator*(const IndexInterface<I1,Meta1>& a,
|
inline decltype(auto) operator*(const IndexInterface<I1,Meta1>& a,
|
||||||
const IndexInterface<I2,Meta2>& b);
|
const IndexInterface<I2,Meta2>& b);
|
||||||
|
|
||||||
|
/** Extend static index pack on the l.h.s.
|
||||||
|
@param a Index to be appended.
|
||||||
|
@param b Index pack to be extended.
|
||||||
|
@return Extended pack.
|
||||||
|
*/
|
||||||
template <class I1, typename Meta1, class... Indices>
|
template <class I1, typename Meta1, class... Indices>
|
||||||
inline decltype(auto) operator*(const IndexInterface<I1,Meta1>& a,
|
inline decltype(auto) operator*(const IndexInterface<I1,Meta1>& a,
|
||||||
const SPack<Indices...>& b);
|
const SPack<Indices...>& b);
|
||||||
|
|
||||||
|
/** Extend static index pack on the r.h.s.
|
||||||
|
@param a Index pack to be extended.
|
||||||
|
@param b Index to be appended.
|
||||||
|
@return Extended pack.
|
||||||
|
*/
|
||||||
template <class I2, typename Meta2, class... Indices>
|
template <class I2, typename Meta2, class... Indices>
|
||||||
inline decltype(auto) operator*(const SPack<Indices...>& a,
|
inline decltype(auto) operator*(const SPack<Indices...>& a,
|
||||||
const IndexInterface<I2,Meta2>& b);
|
const IndexInterface<I2,Meta2>& b);
|
||||||
|
|
||||||
|
/** Combine two static index packs
|
||||||
|
@param a First Index pack.
|
||||||
|
@param b Second Index pack.
|
||||||
|
@return New index pack. a is appended on the l.h.s. of b.
|
||||||
|
*/
|
||||||
template <class... Indices1, class... Indices2>
|
template <class... Indices1, class... Indices2>
|
||||||
inline decltype(auto) operator*(const SPack<Indices1...>& a, const SPack<Indices2...>& b);
|
inline decltype(auto) operator*(const SPack<Indices1...>& a, const SPack<Indices2...>& b);
|
||||||
|
|
||||||
|
/** Extend dynamic index pack on the l.h.s.
|
||||||
|
@param a Index to be appended.
|
||||||
|
@param b Index pack to be extended.
|
||||||
|
@return Extended pack.
|
||||||
|
*/
|
||||||
template <class I1, typename Meta1>
|
template <class I1, typename Meta1>
|
||||||
inline decltype(auto) operator*(const IndexInterface<I1,Meta1>& a, const DPack& b);
|
inline decltype(auto) operator*(const IndexInterface<I1,Meta1>& a, const DPack& b);
|
||||||
|
|
||||||
|
/** Extend dynamic index pack on the r.h.s.
|
||||||
|
@param a Index pack to be extended.
|
||||||
|
@param b Index to be appended.
|
||||||
|
@return Extended pack.
|
||||||
|
*/
|
||||||
template <class I2, typename Meta2>
|
template <class I2, typename Meta2>
|
||||||
inline decltype(auto) operator*(const DPack& a, const IndexInterface<I2,Meta2>& b);
|
inline decltype(auto) operator*(const DPack& a, const IndexInterface<I2,Meta2>& b);
|
||||||
|
|
||||||
|
/** Combine two dynamic index packs
|
||||||
|
@param a First Index pack.
|
||||||
|
@param b Second Index pack.
|
||||||
|
@return New index pack. a is appended on the l.h.s. of b.
|
||||||
|
*/
|
||||||
inline decltype(auto) operator*(const DPack& a, const DPack& b);
|
inline decltype(auto) operator*(const DPack& a, const DPack& b);
|
||||||
|
|
||||||
|
/** Combine two index pointers to an index 2-pack.
|
||||||
|
YIndices and DIndices will be combined into a DPack,
|
||||||
|
otherwise a SPack is returned.
|
||||||
|
@param a First index.
|
||||||
|
@param b Second index.
|
||||||
|
@return Index 2-pack.
|
||||||
|
*/
|
||||||
template <class I1, class I2>
|
template <class I1, class I2>
|
||||||
decltype(auto) iptrMul(const Sptr<I1>& a, const Sptr<I2>& b);
|
decltype(auto) iptrMul(const Sptr<I1>& a, const Sptr<I2>& b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
@file include/ranges/index_traits.h
|
@file include/ranges/index_traits.h
|
||||||
@brief index traits
|
@brief index traits
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
Copyright (c) 2023 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
// -*- C++ -*-
|
|
||||||
/**
|
|
||||||
|
|
||||||
@file include/ranges/index_utils.h
|
|
||||||
@brief ...
|
|
||||||
|
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
|
||||||
Mail: chizeta@f3l.de
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#ifndef __cxz_index_utils_h__
|
|
||||||
#define __cxz_index_utils_h__
|
|
||||||
|
|
||||||
#include "base/base.h"
|
|
||||||
#include "index_base.h"
|
|
||||||
|
|
||||||
namespace CNORXZ
|
|
||||||
{
|
|
||||||
// automatically set static format if SIndices are used!
|
|
||||||
template <class... Indices>
|
|
||||||
constexpr decltype(auto) autoiPtr(const SPack<Indices...>& pack);
|
|
||||||
|
|
||||||
inline SPtr<YIndex> autoiPtr(const DPack& pack);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -2,10 +2,12 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/lindex.h
|
@file include/ranges/lindex.h
|
||||||
@brief ...
|
@brief Statically labeled index.
|
||||||
|
|
||||||
|
Static index labels are usefull to resolve extensions and relations to
|
||||||
|
other indices at compile time.
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -20,7 +22,11 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
// static label to enforce loop unrolling
|
/** ****
|
||||||
|
Statically labeled index.
|
||||||
|
@tparam Index Underlying index.
|
||||||
|
@tparam L Static label.
|
||||||
|
*/
|
||||||
template <class Index, SizeT L>
|
template <class Index, SizeT L>
|
||||||
class LIndex : public Index
|
class LIndex : public Index
|
||||||
{
|
{
|
||||||
|
@ -28,14 +34,25 @@ namespace CNORXZ
|
||||||
typedef typename Index::IB IB;
|
typedef typename Index::IB IB;
|
||||||
typedef typename Index::RangeType RangeType;
|
typedef typename Index::RangeType RangeType;
|
||||||
|
|
||||||
DEFAULT_MEMBERS(LIndex);
|
DEFAULT_MEMBERS(LIndex); /**< Default constructors and assignments. */
|
||||||
|
|
||||||
|
/** Construct from index pointer.
|
||||||
|
@param i Input index.
|
||||||
|
*/
|
||||||
LIndex(const Sptr<Index>& i);
|
LIndex(const Sptr<Index>& i);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::id()
|
||||||
|
Specialization: Static id equals L.
|
||||||
|
*/
|
||||||
IndexId<L> id() const;
|
IndexId<L> id() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stepSize()
|
||||||
|
Specialization: stepSize may be static.
|
||||||
|
*/
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
decltype(auto) stepSize(const IndexId<I>& id) const;
|
decltype(auto) stepSize(const IndexId<I>& id) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stepSize() */
|
||||||
template <class Xpr, class F>
|
template <class Xpr, class F>
|
||||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||||
|
|
||||||
|
@ -43,6 +60,10 @@ namespace CNORXZ
|
||||||
Sptr<Index> mI;
|
Sptr<Index> mI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ***
|
||||||
|
LIndex is an index
|
||||||
|
@see is_index
|
||||||
|
*/
|
||||||
template <class Index, SizeT L>
|
template <class Index, SizeT L>
|
||||||
struct is_index<LIndex<Index,L>>
|
struct is_index<LIndex<Index,L>>
|
||||||
{
|
{
|
||||||
|
@ -59,12 +80,27 @@ namespace CNORXZ
|
||||||
static constexpr bool value = index_expression_exists<Index>::value;
|
static constexpr bool value = index_expression_exists<Index>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Specialize index multiplication for LIndex.
|
||||||
|
@param a Pointer to first index which is a LIndex.
|
||||||
|
@param b Pointer to second index of arbitrary type.
|
||||||
|
@return Resulting index pack.
|
||||||
|
*/
|
||||||
template <class Index, SizeT L, class I1>
|
template <class Index, SizeT L, class I1>
|
||||||
decltype(auto) operator*(const Sptr<LIndex<Index,L>>& a, const Sptr<I1>& b);
|
decltype(auto) operator*(const Sptr<LIndex<Index,L>>& a, const Sptr<I1>& b);
|
||||||
|
|
||||||
|
/** Create LIndex from index pointer.
|
||||||
|
@param i Input index.
|
||||||
|
@tparam L Static label.
|
||||||
|
@return Resulting LIndex.
|
||||||
|
*/
|
||||||
template <SizeT L, class Index>
|
template <SizeT L, class Index>
|
||||||
decltype(auto) lindexPtr(const Sptr<Index>& i);
|
decltype(auto) lindexPtr(const Sptr<Index>& i);
|
||||||
|
|
||||||
|
/** Create LIndex from index pointer.
|
||||||
|
@param i Input index.
|
||||||
|
@param l CSizeT indicating the static label.
|
||||||
|
@return Resulting LIndex.
|
||||||
|
*/
|
||||||
template <class Index, SizeT L>
|
template <class Index, SizeT L>
|
||||||
decltype(auto) lindexPtr(const Sptr<Index>& i, CSizeT<L> l);
|
decltype(auto) lindexPtr(const Sptr<Index>& i, CSizeT<L> l);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/mrange.cc.h
|
@file include/ranges/mrange.cc.h
|
||||||
@brief ...
|
@brief MRange, GMIndex and MIndex, member definition.
|
||||||
|
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -21,9 +21,9 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
/************************
|
/*=========================+
|
||||||
* GMIndex (private) *
|
| GMIndex (private) |
|
||||||
************************/
|
+=========================*/
|
||||||
|
|
||||||
template <class FormatT, class... Indices>
|
template <class FormatT, class... Indices>
|
||||||
template <SizeT... Is>
|
template <SizeT... Is>
|
||||||
|
@ -147,9 +147,9 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************
|
/*===============+
|
||||||
* GMIndex *
|
| GMIndex |
|
||||||
***************/
|
+===============*/
|
||||||
|
|
||||||
template <class FormatT, class... Indices>
|
template <class FormatT, class... Indices>
|
||||||
constexpr GMIndex<FormatT,Indices...>::GMIndex(const GMIndex& i) :
|
constexpr GMIndex<FormatT,Indices...>::GMIndex(const GMIndex& i) :
|
||||||
|
@ -551,15 +551,21 @@ namespace CNORXZ
|
||||||
GMIndex<FormatT,Indices...>&
|
GMIndex<FormatT,Indices...>&
|
||||||
GMIndex<FormatT,Indices...>::reformat(const Vector<SizeT>& f, const Vector<SizeT>& s)
|
GMIndex<FormatT,Indices...>::reformat(const Vector<SizeT>& f, const Vector<SizeT>& s)
|
||||||
{
|
{
|
||||||
|
// f: input format
|
||||||
|
// s: input sizes
|
||||||
|
CXZ_ASSERT(f.size() == s.size(), "input error: f.size() != s.size()");
|
||||||
|
if(f.size() == 1){
|
||||||
|
CXZ_ASSERT(s[0] == lmax().val(), "got inconsistent size; expeected "
|
||||||
|
<< lmax().val() << ", got " << s[0]);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
if constexpr(std::is_same<FormatT,None>::value){
|
if constexpr(std::is_same<FormatT,None>::value){
|
||||||
CXZ_ASSERT(CNORXZ::formatIsTrivial(f,s),
|
CXZ_ASSERT(CNORXZ::formatIsTrivial(f,s),
|
||||||
"cannot reformat MIndex with format type = None");
|
"cannot reformat MIndex with format type = None");
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CXZ_ASSERT(f.size() == s.size(), "input error: f.size() != s.size()");
|
|
||||||
// f: input format
|
|
||||||
// s: input sizes
|
|
||||||
SizeT j = 0;
|
SizeT j = 0;
|
||||||
SizeT j0 = 0;
|
SizeT j0 = 0;
|
||||||
SizeT xi = 1;
|
SizeT xi = 1;
|
||||||
|
@ -590,9 +596,7 @@ namespace CNORXZ
|
||||||
mIPack[i]->reformat(nf,ns);
|
mIPack[i]->reformat(nf,ns);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: IMPLEMENT!!!
|
CXZ_ERROR("reformating with lower-dimensional formats is not possible; use sub-indices instead");
|
||||||
// check trivial format in this partition
|
|
||||||
CXZ_ERROR("reformating with lower-dimensional formats has not yet been implemented");
|
|
||||||
}
|
}
|
||||||
}, NoF {});
|
}, NoF {});
|
||||||
mFormat = FormatT(nformat);
|
mFormat = FormatT(nformat);
|
||||||
|
@ -609,15 +613,6 @@ namespace CNORXZ
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class BT1, class BT2, class... Indices>
|
|
||||||
decltype(auto) replaceFormat(const BT1& bs1, const Sptr<GMIndex<BT2,Indices...>>& gmi)
|
|
||||||
{
|
|
||||||
return iter<0,sizeof...(Indices)>
|
|
||||||
( [&](auto i) { return gmi->pack()[CSizeT<i>{}]; },
|
|
||||||
[&](const auto&... e) { return std::make_shared<GMIndex<BT1,Indices...>>
|
|
||||||
( bs1, e... ); } );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
template <class... Indices>
|
||||||
constexpr decltype(auto) mindex(const Sptr<Indices>&... is)
|
constexpr decltype(auto) mindex(const Sptr<Indices>&... is)
|
||||||
{
|
{
|
||||||
|
@ -648,9 +643,9 @@ namespace CNORXZ
|
||||||
return iptrMul(a, b);
|
return iptrMul(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************
|
/*=====================+
|
||||||
* MRangeFactory *
|
| MRangeFactory |
|
||||||
*********************/
|
+=====================*/
|
||||||
|
|
||||||
template <class... Ranges>
|
template <class... Ranges>
|
||||||
MRangeFactory<Ranges...>::MRangeFactory(const Tuple<Sptr<Ranges>...>& rs) :
|
MRangeFactory<Ranges...>::MRangeFactory(const Tuple<Sptr<Ranges>...>& rs) :
|
||||||
|
@ -679,9 +674,9 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************
|
/*==============+
|
||||||
* MRange *
|
| MRange |
|
||||||
**************/
|
+==============*/
|
||||||
|
|
||||||
template <class... Ranges>
|
template <class... Ranges>
|
||||||
MRange<Ranges...>::MRange(const Tuple<Sptr<Ranges>...>& rs) :
|
MRange<Ranges...>::MRange(const Tuple<Sptr<Ranges>...>& rs) :
|
||||||
|
@ -699,7 +694,6 @@ namespace CNORXZ
|
||||||
template <class... Ranges>
|
template <class... Ranges>
|
||||||
MArray<RangePtr> MRange<Ranges...>::sub() const
|
MArray<RangePtr> MRange<Ranges...>::sub() const
|
||||||
{
|
{
|
||||||
// TODO: ZRange (meta and index pos static!)
|
|
||||||
if constexpr(NR == 0) {
|
if constexpr(NR == 0) {
|
||||||
return MArray<RangePtr>();
|
return MArray<RangePtr>();
|
||||||
}
|
}
|
||||||
|
@ -787,9 +781,9 @@ namespace CNORXZ
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************
|
/*========================+
|
||||||
* MRange (private) *
|
| MRange (private) |
|
||||||
************************/
|
+========================*/
|
||||||
|
|
||||||
template <class... Ranges>
|
template <class... Ranges>
|
||||||
decltype(auto) MRange<Ranges...>::mkA() const
|
decltype(auto) MRange<Ranges...>::mkA() const
|
||||||
|
@ -798,9 +792,9 @@ namespace CNORXZ
|
||||||
[](const auto&... xs) { return Arr<RangePtr,NR> { xs... }; } );
|
[](const auto&... xs) { return Arr<RangePtr,NR> { xs... }; } );
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************
|
/*============================+
|
||||||
* non-member functions *
|
| non-member functions |
|
||||||
****************************/
|
+============================*/
|
||||||
|
|
||||||
template <class... Ranges>
|
template <class... Ranges>
|
||||||
RangePtr mrange(const Sptr<Ranges>&... rs)
|
RangePtr mrange(const Sptr<Ranges>&... rs)
|
||||||
|
|
|
@ -2,10 +2,15 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/mrange.h
|
@file include/ranges/mrange.h
|
||||||
@brief ...
|
@brief MRange, GMIndex and MIndex declaration.
|
||||||
|
|
||||||
|
MRange is a multi-range consisting of of a compile-time fixed number of sub-ranges.
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
GMIndex and MIndex are multi-index consisting of a compile-time fixed number of sub-indices.
|
||||||
|
The difference between the two index types is that MIndex has a statically trivial format,
|
||||||
|
while GMIndex can have an arbitrary format (MFormat or GMFormat).
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -22,8 +27,13 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
// template <class FormatT, class... Indices>
|
|
||||||
// -> Format + IndexTuple
|
/** ****
|
||||||
|
Multi-index with fixed number of sub-indices of arbitrary type
|
||||||
|
and arbitrary index format.
|
||||||
|
@tparam FormatT Index format type.
|
||||||
|
@tparam Indices Sub-index types.
|
||||||
|
*/
|
||||||
template <class FormatT, class... Indices>
|
template <class FormatT, class... Indices>
|
||||||
class GMIndex : public IndexInterface<GMIndex<FormatT,Indices...>,
|
class GMIndex : public IndexInterface<GMIndex<FormatT,Indices...>,
|
||||||
Tuple<typename Indices::MetaType...> >
|
Tuple<typename Indices::MetaType...> >
|
||||||
|
@ -32,75 +42,146 @@ namespace CNORXZ
|
||||||
|
|
||||||
typedef IndexInterface<GMIndex<FormatT,Indices...>,
|
typedef IndexInterface<GMIndex<FormatT,Indices...>,
|
||||||
Tuple<typename Indices::MetaType...>> IB;
|
Tuple<typename Indices::MetaType...>> IB;
|
||||||
//typedef Tuple<Sptr<Indices>...> IndexPack;
|
|
||||||
typedef Tuple<typename Indices::MetaType...> MetaType;
|
typedef Tuple<typename Indices::MetaType...> MetaType;
|
||||||
typedef MRange<typename Indices::RangeType...> RangeType;
|
typedef MRange<typename Indices::RangeType...> RangeType;
|
||||||
static constexpr SizeT NI = sizeof...(Indices);
|
static constexpr SizeT NI = sizeof...(Indices);
|
||||||
|
|
||||||
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
||||||
|
|
||||||
|
/** Default constructor. */
|
||||||
constexpr GMIndex() = default;
|
constexpr GMIndex() = default;
|
||||||
|
|
||||||
|
/** Move constructor (default). */
|
||||||
constexpr GMIndex(GMIndex&& i) = default;
|
constexpr GMIndex(GMIndex&& i) = default;
|
||||||
|
|
||||||
|
/** Move assignment (default). */
|
||||||
constexpr GMIndex& operator=(GMIndex&& i) = default;
|
constexpr GMIndex& operator=(GMIndex&& i) = default;
|
||||||
// no defaults:
|
|
||||||
|
/** Copy constructor (no default, copy sub-index instances). */
|
||||||
constexpr GMIndex(const GMIndex& i);
|
constexpr GMIndex(const GMIndex& i);
|
||||||
|
|
||||||
|
/** Copy assignment (no default, copy sub-index instances). */
|
||||||
constexpr GMIndex& operator=(const GMIndex& i);
|
constexpr GMIndex& operator=(const GMIndex& i);
|
||||||
|
|
||||||
|
/** Construct from index pack. */
|
||||||
constexpr GMIndex(const SPack<Indices...>& pack);
|
constexpr GMIndex(const SPack<Indices...>& pack);
|
||||||
|
|
||||||
|
/** Construct from index pack and format. */
|
||||||
constexpr GMIndex(const FormatT& format, const SPack<Indices...>& pack);
|
constexpr GMIndex(const FormatT& format, const SPack<Indices...>& pack);
|
||||||
|
|
||||||
|
/** Construct from index pointers. */
|
||||||
constexpr GMIndex(const Sptr<Indices>&... is);
|
constexpr GMIndex(const Sptr<Indices>&... is);
|
||||||
|
|
||||||
|
/** Construct from index pointers and format. */
|
||||||
constexpr GMIndex(const FormatT& format, const Sptr<Indices>&... is);
|
constexpr GMIndex(const FormatT& format, const Sptr<Indices>&... is);
|
||||||
|
|
||||||
|
/** Construct from range. */
|
||||||
constexpr GMIndex(const RangePtr& range, SizeT lexpos = 0);
|
constexpr GMIndex(const RangePtr& range, SizeT lexpos = 0);
|
||||||
|
|
||||||
|
/** Construct from range and format. */
|
||||||
constexpr GMIndex(const RangePtr& range, const FormatT& format, SizeT lexpos = 0);
|
constexpr GMIndex(const RangePtr& range, const FormatT& format, SizeT lexpos = 0);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||||
GMIndex& operator=(SizeT pos);
|
GMIndex& operator=(SizeT pos);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator++() */
|
||||||
GMIndex& operator++();
|
GMIndex& operator++();
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator--() */
|
||||||
GMIndex& operator--();
|
GMIndex& operator--();
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+() */
|
||||||
GMIndex operator+(Int n) const;
|
GMIndex operator+(Int n) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-() */
|
||||||
GMIndex operator-(Int n) const;
|
GMIndex operator-(Int n) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-(CIndex) */
|
||||||
SizeT operator-(const GMIndex& i) const;
|
SizeT operator-(const GMIndex& i) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+=() */
|
||||||
GMIndex& operator+=(Int n);
|
GMIndex& operator+=(Int n);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-=() */
|
||||||
GMIndex& operator-=(Int n);
|
GMIndex& operator-=(Int n);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lex() */
|
||||||
SizeT lex() const;
|
SizeT lex() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::pmax() */
|
||||||
constexpr decltype(auto) pmax() const;
|
constexpr decltype(auto) pmax() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lmax() */
|
||||||
constexpr decltype(auto) lmax() const;
|
constexpr decltype(auto) lmax() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::id() */
|
||||||
IndexId<0> id() const;
|
IndexId<0> id() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator*() */
|
||||||
MetaType operator*() const;
|
MetaType operator*() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::dim() */
|
||||||
constexpr SizeT dim() const;
|
constexpr SizeT dim() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::range() */
|
||||||
Sptr<RangeType> range() const;
|
Sptr<RangeType> range() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stepSize() */
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
decltype(auto) stepSize(const IndexId<I>& id) const;
|
decltype(auto) stepSize(const IndexId<I>& id) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stringMeta() */
|
||||||
String stringMeta() const;
|
String stringMeta() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::meta() */
|
||||||
MetaType meta() const;
|
MetaType meta() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::at() */
|
||||||
GMIndex& at(const MetaType& metaPos);
|
GMIndex& at(const MetaType& metaPos);
|
||||||
decltype(auto) xpr(const Sptr<MIndex<Indices...>>& _this) const;
|
|
||||||
|
|
||||||
template <class Xpr, class F>
|
/** @copydoc IndexInterface::prange() */
|
||||||
constexpr decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
|
||||||
|
|
||||||
// replace sub-index instances; only use if you know what you are doing!
|
|
||||||
GMIndex& operator()(const Sptr<MIndex<Indices...>>& mi);
|
|
||||||
GMIndex& operator()();
|
|
||||||
|
|
||||||
const SPack<Indices...>& pack() const;
|
|
||||||
const auto& format() const;
|
|
||||||
const auto& lexFormat() const;
|
|
||||||
RangePtr prange(const GMIndex<FormatT,Indices...>& last) const;
|
RangePtr prange(const GMIndex<FormatT,Indices...>& last) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepFormat() */
|
||||||
auto deepFormat() const;
|
auto deepFormat() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepMax() */
|
||||||
auto deepMax() const;
|
auto deepMax() const;
|
||||||
|
|
||||||
/** @copydoc IndexInterface::reformat() */
|
/** @copydoc IndexInterface::reformat() */
|
||||||
GMIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
GMIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
||||||
|
|
||||||
GMIndex& setFormat(const FormatT& bs);
|
/** @copydoc IndexInterface::ifor() */
|
||||||
|
template <class Xpr, class F>
|
||||||
|
constexpr decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||||
|
|
||||||
/** @copydoc IndexInterface::formatIsTrivial() */
|
/** @copydoc IndexInterface::formatIsTrivial() */
|
||||||
bool formatIsTrivial() const;
|
bool formatIsTrivial() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::xpr() */
|
||||||
|
decltype(auto) xpr(const Sptr<MIndex<Indices...>>& _this) const;
|
||||||
|
|
||||||
|
// replace sub-index instances; only use if you know what you are doing!
|
||||||
|
/** Replace sub-index instances and update index position correspondingly.
|
||||||
|
@param new index instances.
|
||||||
|
*/
|
||||||
|
GMIndex& operator()(const Sptr<MIndex<Indices...>>& mi);
|
||||||
|
|
||||||
|
/** Update index position according to the sub-indices. */
|
||||||
|
GMIndex& operator()();
|
||||||
|
|
||||||
|
/** Get index pack. */
|
||||||
|
const SPack<Indices...>& pack() const;
|
||||||
|
|
||||||
|
/** Get index format. */
|
||||||
|
const auto& format() const;
|
||||||
|
|
||||||
|
/** Get lexicographic index format. */
|
||||||
|
const auto& lexFormat() const;
|
||||||
|
|
||||||
|
/** Assign new index format. */
|
||||||
|
GMIndex& setFormat(const FormatT& bs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <SizeT... Is>
|
template <SizeT... Is>
|
||||||
static constexpr decltype(auto) mkLexFormat(const SPack<Indices...>& ipack, Isq<Is...> is);
|
static constexpr decltype(auto) mkLexFormat(const SPack<Indices...>& ipack, Isq<Is...> is);
|
||||||
|
@ -135,53 +216,114 @@ namespace CNORXZ
|
||||||
PMaxT mPMax;
|
PMaxT mPMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class BT1, class BT2, class... Indices>
|
/** ****
|
||||||
decltype(auto) replaceFormat(const BT1& bs1, const Sptr<GMIndex<BT2,Indices...>>& gmi);
|
Specialization of index_has_const_size for GMIndex.
|
||||||
|
@see index_has_const_size
|
||||||
template <class... Indices>
|
*/
|
||||||
struct index_has_const_size<MIndex<Indices...>>
|
template <class FormatT, class... Indices>
|
||||||
|
struct index_has_const_size<GMIndex<FormatT,Indices...>>
|
||||||
{ static constexpr bool value = (index_has_const_size<Indices>::value and ...); };
|
{ static constexpr bool value = (index_has_const_size<Indices>::value and ...); };
|
||||||
|
|
||||||
template <class... Indices>
|
/** ****
|
||||||
struct index_const_size<MIndex<Indices...>>
|
Specialization of index_const_size for GMIndex.
|
||||||
|
@see index_const_size
|
||||||
|
*/
|
||||||
|
template <class FormatT, class... Indices>
|
||||||
|
struct index_const_size<GMIndex<FormatT,Indices...>>
|
||||||
{ static constexpr SizeT value = (index_const_size<Indices>::value * ...); };
|
{ static constexpr SizeT value = (index_const_size<Indices>::value * ...); };
|
||||||
|
|
||||||
template <class... Indices>
|
/** ****
|
||||||
struct index_dim<MIndex<Indices...>>
|
Specialization of index_dim for GMIndex.
|
||||||
|
@see index_dim
|
||||||
|
*/
|
||||||
|
template <class FormatT, class... Indices>
|
||||||
|
struct index_dim<GMIndex<FormatT,Indices...>>
|
||||||
{ static constexpr SizeT value = sizeof...(Indices); };
|
{ static constexpr SizeT value = sizeof...(Indices); };
|
||||||
|
|
||||||
template <class... Indices>
|
/** ****
|
||||||
struct has_sub<MIndex<Indices...>>
|
Specialization of has_sub for GMIndex.
|
||||||
|
@see has_sub
|
||||||
|
*/
|
||||||
|
template <class FormatT, class... Indices>
|
||||||
|
struct has_sub<GMIndex<FormatT,Indices...>>
|
||||||
{ static constexpr bool value = true; };
|
{ static constexpr bool value = true; };
|
||||||
|
|
||||||
template <class... Indices>
|
/** ****
|
||||||
struct has_static_sub<MIndex<Indices...>>
|
Specialization of has_static_sub for GMIndex.
|
||||||
|
@see has_static_sub
|
||||||
|
*/
|
||||||
|
template <class FormatT, class... Indices>
|
||||||
|
struct has_static_sub<GMIndex<FormatT,Indices...>>
|
||||||
{ static constexpr bool value = true; };
|
{ static constexpr bool value = true; };
|
||||||
|
|
||||||
template <class... Indices>
|
/** ****
|
||||||
struct index_is_multi<MIndex<Indices...>>
|
Specialization of index_is_multi for GMIndex.
|
||||||
|
@see index_is_multi
|
||||||
|
*/
|
||||||
|
template <class FormatT, class... Indices>
|
||||||
|
struct index_is_multi<GMIndex<FormatT,Indices...>>
|
||||||
{ static constexpr bool value = true; };
|
{ static constexpr bool value = true; };
|
||||||
|
|
||||||
|
/** ***
|
||||||
|
MIndex can be used as expression if all its sub-indices can be used as expression
|
||||||
|
@see index_expression_exists
|
||||||
|
*/
|
||||||
|
template <class... Indices>
|
||||||
|
struct index_expression_exists<MIndex<Indices...>>
|
||||||
|
{
|
||||||
|
static constexpr bool value = (index_expression_exists<Indices>::value and ...);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Create MIndex from index pointers.
|
||||||
|
@param is Input index pointers.
|
||||||
|
*/
|
||||||
template <class... Indices>
|
template <class... Indices>
|
||||||
constexpr decltype(auto) mindex(const Sptr<Indices>&... is);
|
constexpr decltype(auto) mindex(const Sptr<Indices>&... is);
|
||||||
|
|
||||||
|
/** Create MIndex from index pack.
|
||||||
|
@param pack Pack of input indices.
|
||||||
|
*/
|
||||||
template <class... Indices>
|
template <class... Indices>
|
||||||
constexpr decltype(auto) mindex(const SPack<Indices...>& pack);
|
constexpr decltype(auto) mindex(const SPack<Indices...>& pack);
|
||||||
|
|
||||||
|
/** Create pointer to MIndex from index pack.
|
||||||
|
@param pack Pack of input indices.
|
||||||
|
*/
|
||||||
template <class... Indices>
|
template <class... Indices>
|
||||||
constexpr decltype(auto) mindexPtr(const SPack<Indices...>& pack);
|
constexpr decltype(auto) mindexPtr(const SPack<Indices...>& pack);
|
||||||
|
|
||||||
|
/** Create pointer to GMIndex from index pack and format.
|
||||||
|
@param bs Index format.
|
||||||
|
@param pack Pack of input indices.
|
||||||
|
*/
|
||||||
template <class FormatT, class... Indices>
|
template <class FormatT, class... Indices>
|
||||||
constexpr decltype(auto) gmindexPtr(const FormatT& bs, const SPack<Indices...>& pack);
|
constexpr decltype(auto) gmindexPtr(const FormatT& bs, const SPack<Indices...>& pack);
|
||||||
|
|
||||||
|
/** Specialization for index multiplication with GMIndex on the l.h.s.
|
||||||
|
@param a First index of type GMIndex.
|
||||||
|
@param b Second index of arbitrary type.
|
||||||
|
*/
|
||||||
template <class I1, class FormatT, class... Indices>
|
template <class I1, class FormatT, class... Indices>
|
||||||
decltype(auto) operator*(const Sptr<GMIndex<FormatT,Indices...>>& a, const Sptr<I1>& b);
|
decltype(auto) operator*(const Sptr<GMIndex<FormatT,Indices...>>& a, const Sptr<I1>& b);
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Specific factory for MRange.
|
||||||
|
@tparam Ranges Types of the sub-ranges.
|
||||||
|
*/
|
||||||
template <class... Ranges>
|
template <class... Ranges>
|
||||||
class MRangeFactory : public RangeFactoryBase
|
class MRangeFactory : public RangeFactoryBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param rs Tuple of sub-ranges.
|
||||||
|
*/
|
||||||
MRangeFactory(const Tuple<Sptr<Ranges>...>& rs);
|
MRangeFactory(const Tuple<Sptr<Ranges>...>& rs);
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param rs Tuple of sub-ranges.
|
||||||
|
@param ref Range the range to be constructed is related to.
|
||||||
|
*/
|
||||||
MRangeFactory(const Tuple<Sptr<Ranges>...>& rs, const RangePtr& ref);
|
MRangeFactory(const Tuple<Sptr<Ranges>...>& rs, const RangePtr& ref);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -192,6 +334,10 @@ namespace CNORXZ
|
||||||
RangePtr mRef;
|
RangePtr mRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Multi Range with compile-time fixed number of sub-ranges
|
||||||
|
of compile-time fixed type.
|
||||||
|
*/
|
||||||
template <class... Ranges>
|
template <class... Ranges>
|
||||||
class MRange : public RangeInterface<MRange<Ranges...>>
|
class MRange : public RangeInterface<MRange<Ranges...>>
|
||||||
{
|
{
|
||||||
|
@ -212,18 +358,34 @@ namespace CNORXZ
|
||||||
virtual const TypeInfo& metaType() const override final;
|
virtual const TypeInfo& metaType() const override final;
|
||||||
virtual RangePtr extend(const RangePtr& r) const override final;
|
virtual RangePtr extend(const RangePtr& r) const override final;
|
||||||
|
|
||||||
|
/** Get sub-ranges. */
|
||||||
decltype(auto) space() const;
|
decltype(auto) space() const;
|
||||||
|
|
||||||
|
/** Get sub-range.
|
||||||
|
@param pos Position of the sub-range.
|
||||||
|
*/
|
||||||
const MetaType get(SizeT pos) const;
|
const MetaType get(SizeT pos) const;
|
||||||
|
|
||||||
|
/** Get lexicographic position according to the given meta data value.
|
||||||
|
@param metaPos Meta data value.
|
||||||
|
*/
|
||||||
SizeT getMeta(const MetaType& metaPos) const;
|
SizeT getMeta(const MetaType& metaPos) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/** Dafault constructor */
|
||||||
MRange() = default;
|
MRange() = default;
|
||||||
|
|
||||||
MRange(const MRange& in) = delete;
|
MRange(const MRange& in) = delete;
|
||||||
MRange& operator=(const MRange& in) = delete;
|
MRange& operator=(const MRange& in) = delete;
|
||||||
|
|
||||||
|
/** Construct from sub-ranges
|
||||||
|
@param rs Tuple of pointers to sub-ranges.
|
||||||
|
*/
|
||||||
MRange(const Tuple<Sptr<Ranges>...>& rs);
|
MRange(const Tuple<Sptr<Ranges>...>& rs);
|
||||||
|
|
||||||
Tuple<Sptr<Ranges>...> mRs;
|
Tuple<Sptr<Ranges>...> mRs; /**< Tuple of pointers to sub-ranges. */
|
||||||
Arr<RangePtr,NR> mA;
|
Arr<RangePtr,NR> mA; /**< Array of abstract base pointers to sub-ranges. Redundant to mRs */
|
||||||
|
|
||||||
virtual Vector<Uuid> key() const override final;
|
virtual Vector<Uuid> key() const override final;
|
||||||
private:
|
private:
|
||||||
|
@ -231,24 +393,22 @@ namespace CNORXZ
|
||||||
decltype(auto) mkA() const;
|
decltype(auto) mkA() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Create MRange pointer.
|
||||||
|
@param rs Pointer to sub-ranges.
|
||||||
|
*/
|
||||||
template <class... Ranges>
|
template <class... Ranges>
|
||||||
RangePtr mrange(const Sptr<Ranges>&... rs);
|
RangePtr mrange(const Sptr<Ranges>&... rs);
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Specialization of RangeCast for MRange.
|
||||||
|
@see RangeCast.
|
||||||
|
*/
|
||||||
template <class... Ranges>
|
template <class... Ranges>
|
||||||
struct RangeCast<MRange<Ranges...>>
|
struct RangeCast<MRange<Ranges...>>
|
||||||
{
|
{
|
||||||
static Sptr<MRange<Ranges...>> func(const RangePtr& r);
|
static Sptr<MRange<Ranges...>> func(const RangePtr& r);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** ***
|
|
||||||
MIndex can be used as expression if all its sub-indices can be used as expression
|
|
||||||
@see index_expression_exists
|
|
||||||
*/
|
|
||||||
template <class... Indices>
|
|
||||||
struct index_expression_exists<MIndex<Indices...>>
|
|
||||||
{
|
|
||||||
static constexpr bool value = (index_expression_exists<Indices>::value and ...);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/prange.cc.h
|
@file include/ranges/prange.cc.h
|
||||||
@brief ...
|
@brief PRange, PRangeFactory and PIndex implementations.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -18,9 +17,9 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
/**************
|
/*============+
|
||||||
* PIndex *
|
| PIndex |
|
||||||
**************/
|
+============*/
|
||||||
|
|
||||||
template <class IndexT>
|
template <class IndexT>
|
||||||
PIndex<IndexT>::PIndex(const RangePtr& range, SizeT pos) :
|
PIndex<IndexT>::PIndex(const RangePtr& range, SizeT pos) :
|
||||||
|
@ -206,9 +205,7 @@ namespace CNORXZ
|
||||||
template <class IndexT>
|
template <class IndexT>
|
||||||
decltype(auto) PIndex<IndexT>::xpr(const Sptr<PIndex<IndexT>>& _this) const
|
decltype(auto) PIndex<IndexT>::xpr(const Sptr<PIndex<IndexT>>& _this) const
|
||||||
{
|
{
|
||||||
CXZ_ERROR("implement!!!");
|
return poproot( _this, mRangePtr->parts(), mOrig->xpr(mOrig) );
|
||||||
//return poperation( _this, mOrig, mRangePtr->parts(), mOrig->xpr(mOrig) );
|
|
||||||
return mOrig->xpr(mOrig);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexT>
|
template <class IndexT>
|
||||||
|
@ -246,9 +243,9 @@ namespace CNORXZ
|
||||||
return mOrig;
|
return mOrig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************
|
/*======================+
|
||||||
* PIndex (private) *
|
| PIndex (private) |
|
||||||
************************/
|
+======================*/
|
||||||
|
|
||||||
template <class IndexT>
|
template <class IndexT>
|
||||||
void PIndex<IndexT>::mkPos()
|
void PIndex<IndexT>::mkPos()
|
||||||
|
@ -264,9 +261,9 @@ namespace CNORXZ
|
||||||
CXZ_ERROR("meta position '" << toString(mOrig->meta()) << "' not part of range");
|
CXZ_ERROR("meta position '" << toString(mOrig->meta()) << "' not part of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************
|
/*=========================+
|
||||||
* PIndex (non-member) *
|
| PIndex (non-member) |
|
||||||
***************************/
|
+=========================*/
|
||||||
|
|
||||||
template <class I, class I1>
|
template <class I, class I1>
|
||||||
decltype(auto) operator*(const Sptr<PIndex<I>>& a, const Sptr<I1>& b)
|
decltype(auto) operator*(const Sptr<PIndex<I>>& a, const Sptr<I1>& b)
|
||||||
|
@ -274,9 +271,9 @@ namespace CNORXZ
|
||||||
return iptrMul(a, b);
|
return iptrMul(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************
|
/*===================+
|
||||||
* PRangeFactory *
|
| PRangeFactory |
|
||||||
*********************/
|
+===================*/
|
||||||
|
|
||||||
template <class RangeT>
|
template <class RangeT>
|
||||||
PRangeFactory<RangeT>::PRangeFactory(const Sptr<RangeT>& range, const Vector<SizeT>& _parts) :
|
PRangeFactory<RangeT>::PRangeFactory(const Sptr<RangeT>& range, const Vector<SizeT>& _parts) :
|
||||||
|
@ -301,9 +298,9 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************
|
/*============+
|
||||||
* PRange *
|
| PRange |
|
||||||
**************/
|
+============*/
|
||||||
|
|
||||||
template <class RangeT>
|
template <class RangeT>
|
||||||
SizeT PRange<RangeT>::size() const
|
SizeT PRange<RangeT>::size() const
|
||||||
|
@ -338,10 +335,19 @@ namespace CNORXZ
|
||||||
template <class RangeT>
|
template <class RangeT>
|
||||||
RangePtr PRange<RangeT>::extend(const RangePtr& r) const
|
RangePtr PRange<RangeT>::extend(const RangePtr& r) const
|
||||||
{
|
{
|
||||||
CXZ_ERROR("implement!!!");
|
if(r->type() == type()){
|
||||||
// if r is PRange of same Range, then just add parts
|
Sptr<PRange<RangeT>> rx = std::dynamic_pointer_cast<PRange<RangeT>>(r);
|
||||||
// else derive and add meta of r
|
if(rx->orig() == orig()){
|
||||||
return nullptr;
|
Vector<SizeT> p(parts());
|
||||||
|
for(auto i: rx->parts()){
|
||||||
|
if(find(p.begin(), p.end(), i) != p.end()){
|
||||||
|
p.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prange(orig(), p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return derive()->extend(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class RangeT>
|
template <class RangeT>
|
||||||
|
@ -361,16 +367,17 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
Vector<MetaType> meta(this->size());
|
Vector<MetaType> meta(this->size());
|
||||||
auto i = mRange->begin();
|
auto i = mRange->begin();
|
||||||
|
SizeT j = 0;
|
||||||
for(const auto& p: mParts){
|
for(const auto& p: mParts){
|
||||||
meta = *(i = p);
|
meta[j++] = *(i = p);
|
||||||
}
|
}
|
||||||
return URangeFactory<MetaType>( meta ).create();
|
return URangeFactory<MetaType>( meta ).create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************
|
/*======================+
|
||||||
* PRange (private) *
|
| PRange (private) |
|
||||||
************************/
|
+======================*/
|
||||||
|
|
||||||
template <class RangeT>
|
template <class RangeT>
|
||||||
PRange<RangeT>::PRange(const Sptr<RangeT>& range, const Vector<SizeT>& _parts) :
|
PRange<RangeT>::PRange(const Sptr<RangeT>& range, const Vector<SizeT>& _parts) :
|
||||||
|
@ -386,9 +393,9 @@ namespace CNORXZ
|
||||||
return Vector<Uuid> { mRange->id() };
|
return Vector<Uuid> { mRange->id() };
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************
|
/*==========================+
|
||||||
* non-member functions *
|
| non-member functions |
|
||||||
****************************/
|
+==========================*/
|
||||||
|
|
||||||
template <class RangeT>
|
template <class RangeT>
|
||||||
RangePtr prange(const Sptr<RangeT>& range, const Vector<SizeT>& parts)
|
RangePtr prange(const Sptr<RangeT>& range, const Vector<SizeT>& parts)
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/prange.h
|
@file include/ranges/prange.h
|
||||||
@brief ...
|
@brief PRange, PRangeFactory and PIndex declaration.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -20,7 +19,10 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
/** ****
|
||||||
|
Index specific for PRange.
|
||||||
|
@tparam IndexT Full index type.
|
||||||
|
*/
|
||||||
template <class IndexT>
|
template <class IndexT>
|
||||||
class PIndex : public IndexInterface<PIndex<IndexT>,typename IndexT::MetaType>
|
class PIndex : public IndexInterface<PIndex<IndexT>,typename IndexT::MetaType>
|
||||||
{
|
{
|
||||||
|
@ -30,51 +32,105 @@ namespace CNORXZ
|
||||||
typedef PRange<typename IndexT::RangeType> RangeType;
|
typedef PRange<typename IndexT::RangeType> RangeType;
|
||||||
typedef typename IndexT::MetaType MetaType;
|
typedef typename IndexT::MetaType MetaType;
|
||||||
|
|
||||||
|
/** Constructor.
|
||||||
|
@param range Range to define index on.
|
||||||
|
@param pos Initial lexicographic position (default = 0).
|
||||||
|
*/
|
||||||
PIndex(const RangePtr& range, SizeT pos = 0);
|
PIndex(const RangePtr& range, SizeT pos = 0);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||||
PIndex& operator=(SizeT lexpos);
|
PIndex& operator=(SizeT lexpos);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator++() */
|
||||||
PIndex& operator++();
|
PIndex& operator++();
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator--() */
|
||||||
PIndex& operator--();
|
PIndex& operator--();
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+() */
|
||||||
PIndex operator+(Int n) const;
|
PIndex operator+(Int n) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-() */
|
||||||
PIndex operator-(Int n) const;
|
PIndex operator-(Int n) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-(PIndex) */
|
||||||
SizeT operator-(const PIndex& i) const;
|
SizeT operator-(const PIndex& i) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+=() */
|
||||||
PIndex& operator+=(Int n);
|
PIndex& operator+=(Int n);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-=() */
|
||||||
PIndex& operator-=(Int n);
|
PIndex& operator-=(Int n);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lex() */
|
||||||
SizeT lex() const;
|
SizeT lex() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::pmax() */
|
||||||
UPos pmax() const;
|
UPos pmax() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lmax() */
|
||||||
UPos lmax() const;
|
UPos lmax() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::id() */
|
||||||
IndexId<0> id() const;
|
IndexId<0> id() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator*() */
|
||||||
decltype(auto) operator*() const;
|
decltype(auto) operator*() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::dim() */
|
||||||
SizeT dim() const;
|
SizeT dim() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::range() */
|
||||||
Sptr<RangeType> range() const;
|
Sptr<RangeType> range() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stepSize() */
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
UPos stepSize(const IndexId<I>& id) const;
|
UPos stepSize(const IndexId<I>& id) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stringMeta() */
|
||||||
|
String stringMeta() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::meta() */
|
||||||
|
decltype(auto) meta() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::at() */
|
||||||
|
PIndex& at(const MetaType& metaPos);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::prange() */
|
||||||
RangePtr prange(const PIndex<IndexT>& last) const;
|
RangePtr prange(const PIndex<IndexT>& last) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepFormat() */
|
||||||
decltype(auto) deepFormat() const;
|
decltype(auto) deepFormat() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepMax() */
|
||||||
decltype(auto) deepMax() const;
|
decltype(auto) deepMax() const;
|
||||||
|
|
||||||
/** @copydoc IndexInterface::reformat() */
|
/** @copydoc IndexInterface::reformat() */
|
||||||
PIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
PIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
||||||
|
|
||||||
String stringMeta() const;
|
/** @copydoc IndexInterface::ifor() */
|
||||||
decltype(auto) meta() const;
|
|
||||||
PIndex& at(const MetaType& metaPos);
|
|
||||||
decltype(auto) xpr(const Sptr<PIndex<IndexT>>& _this) const;
|
|
||||||
|
|
||||||
template <class Xpr, class F>
|
template <class Xpr, class F>
|
||||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||||
|
|
||||||
PIndex& operator()();
|
|
||||||
PIndex& operator()(const Sptr<IndexT>& i);
|
|
||||||
const Sptr<IndexT>& orig() const;
|
|
||||||
|
|
||||||
/** @copydoc IndexInterface::formatIsTrivial() */
|
/** @copydoc IndexInterface::formatIsTrivial() */
|
||||||
bool formatIsTrivial() const;
|
bool formatIsTrivial() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::xpr() */
|
||||||
|
decltype(auto) xpr(const Sptr<PIndex<IndexT>>& _this) const;
|
||||||
|
|
||||||
|
/** Replace instance of index on full range and update current position accordingly.
|
||||||
|
@param i New index instance.
|
||||||
|
*/
|
||||||
|
PIndex& operator()(const Sptr<IndexT>& i);
|
||||||
|
|
||||||
|
/** Update current index position according to the internal index on the full range. */
|
||||||
|
PIndex& operator()();
|
||||||
|
|
||||||
|
/** Get original index.
|
||||||
|
@return Index corresponding to original range and current position.
|
||||||
|
*/
|
||||||
|
const Sptr<IndexT>& orig() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Sptr<RangeType> mRangePtr;
|
Sptr<RangeType> mRangePtr;
|
||||||
Sptr<IndexT> mOrig;
|
Sptr<IndexT> mOrig;
|
||||||
|
@ -82,14 +138,31 @@ namespace CNORXZ
|
||||||
void mkPos();
|
void mkPos();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Make index pack of a PIndex and another index.
|
||||||
|
@param a pointer to PIndex.
|
||||||
|
@param b pointer to another index.
|
||||||
|
*/
|
||||||
template <class I, class I1>
|
template <class I, class I1>
|
||||||
decltype(auto) operator*(const Sptr<PIndex<I>>& a, const Sptr<I1>& b);
|
decltype(auto) operator*(const Sptr<PIndex<I>>& a, const Sptr<I1>& b);
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Specific factory for PRange.
|
||||||
|
*/
|
||||||
template <class RangeT>
|
template <class RangeT>
|
||||||
class PRangeFactory : public RangeFactoryBase
|
class PRangeFactory : public RangeFactoryBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param range Full range (explicit type) the constructed range is part of.
|
||||||
|
@param _parts Integer vector indicating the parts w.r.t. input range to be covered by the PRange.
|
||||||
|
*/
|
||||||
PRangeFactory(const Sptr<RangeT>& range, const Vector<SizeT>& _parts);
|
PRangeFactory(const Sptr<RangeT>& range, const Vector<SizeT>& _parts);
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param range Full range the constructed range is part of.
|
||||||
|
@param _parts Integer vector indicating the parts of the full range.
|
||||||
|
*/
|
||||||
PRangeFactory(const RangePtr& range, const Vector<SizeT>& _parts);
|
PRangeFactory(const RangePtr& range, const Vector<SizeT>& _parts);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -100,6 +173,13 @@ namespace CNORXZ
|
||||||
Vector<SizeT> mParts;
|
Vector<SizeT> mParts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Partial Range.
|
||||||
|
Ranges of these kind represent a part of a given range (full range).
|
||||||
|
Using a mathematical nomenclature, this would be called a "sub-range".
|
||||||
|
(The prefix "sub", as well as the letter "S" are, however, already extensively
|
||||||
|
used in other contexts.)
|
||||||
|
*/
|
||||||
template <class RangeT>
|
template <class RangeT>
|
||||||
class PRange : public RangeInterface<PRange<RangeT>>
|
class PRange : public RangeInterface<PRange<RangeT>>
|
||||||
{
|
{
|
||||||
|
@ -117,8 +197,20 @@ namespace CNORXZ
|
||||||
virtual const TypeInfo& metaType() const override final;
|
virtual const TypeInfo& metaType() const override final;
|
||||||
virtual RangePtr extend(const RangePtr& r) const override final;
|
virtual RangePtr extend(const RangePtr& r) const override final;
|
||||||
|
|
||||||
|
/** Get the full range.
|
||||||
|
@return Pointer to the full range.
|
||||||
|
*/
|
||||||
Sptr<RangeT> orig() const;
|
Sptr<RangeT> orig() const;
|
||||||
|
|
||||||
|
/** Get the parts.
|
||||||
|
@return Integer vector indicating the parts contained by the PRange w.r.t. the full range.
|
||||||
|
*/
|
||||||
const Vector<SizeT>& parts() const;
|
const Vector<SizeT>& parts() const;
|
||||||
|
|
||||||
|
/** Create a new range of the type of the full range but containing only
|
||||||
|
the parts covered by the PRange.
|
||||||
|
@return The created range.
|
||||||
|
*/
|
||||||
RangePtr derive() const;
|
RangePtr derive() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -133,6 +225,11 @@ namespace CNORXZ
|
||||||
Vector<SizeT> mParts;
|
Vector<SizeT> mParts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Create a PRange.
|
||||||
|
Internally calls PRangeFactory.
|
||||||
|
@param range Range to create a PRange on.
|
||||||
|
@param parts Integer vector indicating the parts w.r.t. input range to be covered by the PRange.
|
||||||
|
*/
|
||||||
template <class RangeT>
|
template <class RangeT>
|
||||||
RangePtr prange(const Sptr<RangeT>& range, const Vector<SizeT>& parts);
|
RangePtr prange(const Sptr<RangeT>& range, const Vector<SizeT>& parts);
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/ranges.h
|
@file include/ranges/ranges.h
|
||||||
@brief ...
|
@brief Ranges main header
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/srange.h
|
@file include/ranges/srange.h
|
||||||
@brief ...
|
@brief SRange, SRangeFactory and SIndex declaration.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -20,6 +19,11 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
/** ****
|
||||||
|
Specific index for SRange.
|
||||||
|
@tparam MetaT Meta data type.
|
||||||
|
@tparam S Static size of the range.
|
||||||
|
*/
|
||||||
template <typename MetaT, SizeT S>
|
template <typename MetaT, SizeT S>
|
||||||
class SIndex : public IndexInterface<SIndex<MetaT,S>,MetaT>
|
class SIndex : public IndexInterface<SIndex<MetaT,S>,MetaT>
|
||||||
{
|
{
|
||||||
|
@ -29,43 +33,88 @@ namespace CNORXZ
|
||||||
typedef MetaT MetaType;
|
typedef MetaT MetaType;
|
||||||
|
|
||||||
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
||||||
DEFAULT_MEMBERS(SIndex);
|
DEFAULT_MEMBERS(SIndex); /**< default constructors and assignments */
|
||||||
|
|
||||||
|
/** Construct index from range and position.
|
||||||
|
@param range Range to iterate over.
|
||||||
|
@param pos lexicographic position.
|
||||||
|
*/
|
||||||
SIndex(const RangePtr& range, SizeT pos = 0);
|
SIndex(const RangePtr& range, SizeT pos = 0);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||||
SIndex& operator=(SizeT lexpos);
|
SIndex& operator=(SizeT lexpos);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator++() */
|
||||||
SIndex& operator++();
|
SIndex& operator++();
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator--() */
|
||||||
SIndex& operator--();
|
SIndex& operator--();
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+() */
|
||||||
SIndex operator+(Int n) const;
|
SIndex operator+(Int n) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-() */
|
||||||
SIndex operator-(Int n) const;
|
SIndex operator-(Int n) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-(SIndex) */
|
||||||
SizeT operator-(const SIndex& i) const;
|
SizeT operator-(const SIndex& i) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+=() */
|
||||||
SIndex& operator+=(Int n);
|
SIndex& operator+=(Int n);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-=() */
|
||||||
SIndex& operator-=(Int n);
|
SIndex& operator-=(Int n);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lex() */
|
||||||
SizeT lex() const;
|
SizeT lex() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::pmax() */
|
||||||
SPos<S> pmax() const;
|
SPos<S> pmax() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lmax() */
|
||||||
SPos<S> lmax() const;
|
SPos<S> lmax() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::id() */
|
||||||
IndexId<0> id() const;
|
IndexId<0> id() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator*() */
|
||||||
const MetaT& operator*() const;
|
const MetaT& operator*() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::dim() */
|
||||||
SizeT dim() const; // = 1
|
SizeT dim() const; // = 1
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::range() */
|
||||||
Sptr<RangeType> range() const;
|
Sptr<RangeType> range() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stepSize() */
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
UPos stepSize(const IndexId<I>& id) const;
|
UPos stepSize(const IndexId<I>& id) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stringMeta() */
|
||||||
String stringMeta() const;
|
String stringMeta() const;
|
||||||
const MetaT& meta() const;
|
|
||||||
SIndex& at(const MetaT& metaPos);
|
|
||||||
decltype(auto) xpr(const Sptr<SIndex<MetaType,S>>& _this) const;
|
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::meta() */
|
||||||
|
const MetaT& meta() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::at() */
|
||||||
|
SIndex& at(const MetaT& metaPos);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::prange() */
|
||||||
RangePtr prange(const SIndex<MetaType,S>& last) const;
|
RangePtr prange(const SIndex<MetaType,S>& last) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepFormat() */
|
||||||
SizeT deepFormat() const;
|
SizeT deepFormat() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepMax() */
|
||||||
SizeT deepMax() const;
|
SizeT deepMax() const;
|
||||||
|
|
||||||
/** @copydoc IndexInterface::reformat() */
|
/** @copydoc IndexInterface::reformat() */
|
||||||
SIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
SIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::ifor() */
|
||||||
|
decltype(auto) xpr(const Sptr<SIndex<MetaType,S>>& _this) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::ifor() */
|
||||||
template <class Xpr, class F>
|
template <class Xpr, class F>
|
||||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||||
|
|
||||||
|
@ -77,16 +126,43 @@ namespace CNORXZ
|
||||||
const MetaT* mMetaPtr;
|
const MetaT* mMetaPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Make index pack of a SIndex and another index.
|
||||||
|
@param a pointer to SIndex.
|
||||||
|
@param b pointer to another index.
|
||||||
|
*/
|
||||||
template <typename MetaT, SizeT S, class I1>
|
template <typename MetaT, SizeT S, class I1>
|
||||||
decltype(auto) operator*(const Sptr<SIndex<MetaT,S>>& a, const Sptr<I1>& b);
|
decltype(auto) operator*(const Sptr<SIndex<MetaT,S>>& a, const Sptr<I1>& b);
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Specific factory for SRange.
|
||||||
|
@tparam MetaT Meta data type.
|
||||||
|
@tparam S Static size of the range.
|
||||||
|
*/
|
||||||
template <typename MetaT, SizeT S>
|
template <typename MetaT, SizeT S>
|
||||||
class SRangeFactory : public RangeFactoryBase
|
class SRangeFactory : public RangeFactoryBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param space Meta data array defining the range.
|
||||||
|
*/
|
||||||
SRangeFactory(const Arr<MetaT,S>& space);
|
SRangeFactory(const Arr<MetaT,S>& space);
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param space Meta data array defining the range (move).
|
||||||
|
*/
|
||||||
SRangeFactory(Arr<MetaT,S>&& space);
|
SRangeFactory(Arr<MetaT,S>&& space);
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param space Meta data array defining the range.
|
||||||
|
@param ref Range the range to be constructed is related to.
|
||||||
|
*/
|
||||||
SRangeFactory(const Arr<MetaT,S>& space, const RangePtr& ref);
|
SRangeFactory(const Arr<MetaT,S>& space, const RangePtr& ref);
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param space Meta data array defining the range (move).
|
||||||
|
@param ref Range the range to be constructed is related to.
|
||||||
|
*/
|
||||||
SRangeFactory(Arr<MetaT,S>&& space, const RangePtr& ref);
|
SRangeFactory(Arr<MetaT,S>&& space, const RangePtr& ref);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -97,6 +173,12 @@ namespace CNORXZ
|
||||||
RangePtr mRef;
|
RangePtr mRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Static size range.
|
||||||
|
The same as URange, but the range size is compile-time fixed.
|
||||||
|
@tparam MetaT Meta data type.
|
||||||
|
@tparam S Static range size.
|
||||||
|
*/
|
||||||
template <typename MetaT, SizeT S>
|
template <typename MetaT, SizeT S>
|
||||||
class SRange : public RangeInterface<SRange<MetaT,S>>
|
class SRange : public RangeInterface<SRange<MetaT,S>>
|
||||||
{
|
{
|
||||||
|
@ -114,8 +196,19 @@ namespace CNORXZ
|
||||||
virtual const TypeInfo& metaType() const override final;
|
virtual const TypeInfo& metaType() const override final;
|
||||||
virtual RangePtr extend(const RangePtr& r) const override final;
|
virtual RangePtr extend(const RangePtr& r) const override final;
|
||||||
|
|
||||||
|
/** return meta data at given position.
|
||||||
|
@param pos position, size type
|
||||||
|
*/
|
||||||
const MetaT& get(SizeT pos) const;
|
const MetaT& get(SizeT pos) const;
|
||||||
|
|
||||||
|
/** Get underlying meta data array.
|
||||||
|
@return Pointer to first position of meta data array.
|
||||||
|
*/
|
||||||
const MetaT* get() const;
|
const MetaT* get() const;
|
||||||
|
|
||||||
|
/** return position for given meta data.
|
||||||
|
@param metaPos meta data, size type
|
||||||
|
*/
|
||||||
SizeT getMeta(const MetaT& metaPos) const;
|
SizeT getMeta(const MetaT& metaPos) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -132,9 +225,16 @@ namespace CNORXZ
|
||||||
SERIALIZATION_FUNCTIONS_NOPUB;
|
SERIALIZATION_FUNCTIONS_NOPUB;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ***
|
||||||
|
Specialize RangeCast for casts to SRange
|
||||||
|
@see RangeCast
|
||||||
|
@tparam MetaT Meta data type.
|
||||||
|
@tparam S Static range size.
|
||||||
|
*/
|
||||||
template <typename MetaT, SizeT S>
|
template <typename MetaT, SizeT S>
|
||||||
struct RangeCast<SRange<MetaT,S>>
|
struct RangeCast<SRange<MetaT,S>>
|
||||||
{
|
{
|
||||||
|
/** cast the range */
|
||||||
static Sptr<SRange<MetaT,S>> func(const RangePtr& r);
|
static Sptr<SRange<MetaT,S>> func(const RangePtr& r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,10 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
auto b = mSpace.begin();
|
auto b = mSpace.begin();
|
||||||
auto e = mSpace.end();
|
auto e = mSpace.end();
|
||||||
return std::lower_bound(b, e, meta, std::less<MetaT>()) - b;
|
auto i = std::lower_bound(b, e, meta, std::less<MetaT>());
|
||||||
|
CXZ_ASSERT(i != e, "element with meta data = " << toString(meta) << " not in range"); // check this first, otherwise the next test may potentially result in a seg fault!
|
||||||
|
CXZ_ASSERT(*i == meta, "element with meta data = " << toString(meta) << " not in range");
|
||||||
|
return i - b;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MetaT>
|
template <typename MetaT>
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/urange.h
|
@file include/ranges/urange.h
|
||||||
@brief ...
|
@brief URange, URangeFactory and UIndex declaration.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -23,6 +22,10 @@
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Specific index for URange.
|
||||||
|
@tparam MetaT Meta data type.
|
||||||
|
*/
|
||||||
template <typename MetaT>
|
template <typename MetaT>
|
||||||
class UIndex : public IndexInterface<UIndex<MetaT>,MetaT>
|
class UIndex : public IndexInterface<UIndex<MetaT>,MetaT>
|
||||||
{
|
{
|
||||||
|
@ -33,51 +36,94 @@ namespace CNORXZ
|
||||||
typedef MetaT MetaType;
|
typedef MetaT MetaType;
|
||||||
|
|
||||||
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
||||||
DEFAULT_MEMBERS(UIndex);
|
DEFAULT_MEMBERS(UIndex); /**< default constructors and assignments */
|
||||||
|
|
||||||
|
/** Construct index from range and position.
|
||||||
|
@param range Range to iterate over.
|
||||||
|
@param pos lexicographic position.
|
||||||
|
*/
|
||||||
UIndex(const RangePtr& range, SizeT pos = 0);
|
UIndex(const RangePtr& range, SizeT pos = 0);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||||
UIndex& operator=(SizeT lexpos);
|
UIndex& operator=(SizeT lexpos);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator++() */
|
||||||
UIndex& operator++();
|
UIndex& operator++();
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator--() */
|
||||||
UIndex& operator--();
|
UIndex& operator--();
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+() */
|
||||||
UIndex operator+(Int n) const;
|
UIndex operator+(Int n) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-() */
|
||||||
UIndex operator-(Int n) const;
|
UIndex operator-(Int n) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-(UIndex) */
|
||||||
SizeT operator-(const UIndex& i) const;
|
SizeT operator-(const UIndex& i) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+=() */
|
||||||
UIndex& operator+=(Int n);
|
UIndex& operator+=(Int n);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-=() */
|
||||||
UIndex& operator-=(Int n);
|
UIndex& operator-=(Int n);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lex() */
|
||||||
SizeT lex() const;
|
SizeT lex() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::pmax() */
|
||||||
UPos pmax() const;
|
UPos pmax() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lmax() */
|
||||||
UPos lmax() const;
|
UPos lmax() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::id() */
|
||||||
IndexId<0> id() const;
|
IndexId<0> id() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator*() */
|
||||||
const MetaT& operator*() const;
|
const MetaT& operator*() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::dim() */
|
||||||
SizeT dim() const; // = 1
|
SizeT dim() const; // = 1
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::range() */
|
||||||
Sptr<RangeType> range() const;
|
Sptr<RangeType> range() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stepSize() */
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
decltype(auto) stepSize(const IndexId<I>& id) const;
|
decltype(auto) stepSize(const IndexId<I>& id) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stringMeta() */
|
||||||
String stringMeta() const;
|
String stringMeta() const;
|
||||||
const MetaT& meta() const;
|
|
||||||
UIndex& at(const MetaT& metaPos);
|
|
||||||
decltype(auto) xpr(const Sptr<UIndex<MetaType>>& _this) const;
|
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::meta() */
|
||||||
|
const MetaT& meta() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::at() */
|
||||||
|
UIndex& at(const MetaT& metaPos);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::prange() */
|
||||||
RangePtr prange(const UIndex<MetaType>& last) const;
|
RangePtr prange(const UIndex<MetaType>& last) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepFormat() */
|
||||||
SizeT deepFormat() const;
|
SizeT deepFormat() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepMax() */
|
||||||
SizeT deepMax() const;
|
SizeT deepMax() const;
|
||||||
|
|
||||||
/** @copydoc IndexInterface::reformat() */
|
/** @copydoc IndexInterface::reformat() */
|
||||||
UIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
UIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::ifor() */
|
||||||
template <class Xpr, class F>
|
template <class Xpr, class F>
|
||||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||||
|
|
||||||
/** @copydoc IndexInterface::formatIsTrivial() */
|
/** @copydoc IndexInterface::formatIsTrivial() */
|
||||||
bool formatIsTrivial() const;
|
bool formatIsTrivial() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::xpr() */
|
||||||
|
decltype(auto) xpr(const Sptr<UIndex<MetaType>>& _this) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Sptr<RangeType> mRangePtr;
|
Sptr<RangeType> mRangePtr;
|
||||||
const MetaT* mMetaPtr;
|
const MetaT* mMetaPtr;
|
||||||
|
@ -86,26 +132,39 @@ namespace CNORXZ
|
||||||
template <typename MetaT>
|
template <typename MetaT>
|
||||||
void swap(UIndex<MetaT>& a, UIndex<MetaT>& b) { a.swap(b); }
|
void swap(UIndex<MetaT>& a, UIndex<MetaT>& b) { a.swap(b); }
|
||||||
|
|
||||||
template <typename MetaType, class I1>
|
/** Make index pack of a UIndex and another index.
|
||||||
decltype(auto) operator*(const Sptr<UIndex<MetaType>>& a, const Sptr<I1>& b);
|
@param a pointer to UIndex.
|
||||||
|
@param b pointer to another index.
|
||||||
|
*/
|
||||||
|
template <typename MetaT, class I1>
|
||||||
|
decltype(auto) operator*(const Sptr<UIndex<MetaT>>& a, const Sptr<I1>& b);
|
||||||
|
|
||||||
template <typename MetaType>
|
/** ****
|
||||||
|
Specific factory for URange.
|
||||||
|
@tparam MetaT Meta data type.
|
||||||
|
*/
|
||||||
|
template <typename MetaT>
|
||||||
class URangeFactory : public RangeFactoryBase
|
class URangeFactory : public RangeFactoryBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
URangeFactory(const Vector<MetaType>& space);
|
URangeFactory(const Vector<MetaT>& space);
|
||||||
URangeFactory(Vector<MetaType>&& space);
|
URangeFactory(Vector<MetaT>&& space);
|
||||||
URangeFactory(const Vector<MetaType>& space, const RangePtr& ref);
|
URangeFactory(const Vector<MetaT>& space, const RangePtr& ref);
|
||||||
URangeFactory(Vector<MetaType>&& space, const RangePtr& ref);
|
URangeFactory(Vector<MetaT>&& space, const RangePtr& ref);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
URangeFactory() = default;
|
URangeFactory() = default;
|
||||||
virtual void make() override final;
|
virtual void make() override final;
|
||||||
|
|
||||||
Vector<MetaType> mSpace;
|
Vector<MetaT> mSpace;
|
||||||
RangePtr mRef;
|
RangePtr mRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Uni-(1-)dimensional range with non-trivial meta data space
|
||||||
|
i.e. the parameter space can be arbitrary.
|
||||||
|
@tparam MetaT Meta data type.
|
||||||
|
*/
|
||||||
template <typename MetaT>
|
template <typename MetaT>
|
||||||
class URange : public RangeInterface<URange<MetaT>>
|
class URange : public RangeInterface<URange<MetaT>>
|
||||||
{
|
{
|
||||||
|
@ -123,8 +182,21 @@ namespace CNORXZ
|
||||||
virtual const TypeInfo& metaType() const override final;
|
virtual const TypeInfo& metaType() const override final;
|
||||||
virtual RangePtr extend(const RangePtr& r) const override final;
|
virtual RangePtr extend(const RangePtr& r) const override final;
|
||||||
|
|
||||||
|
/** Get meta data at given range position.
|
||||||
|
@param pos Integer indicating requested position.
|
||||||
|
@return Meta data at given postion.
|
||||||
|
*/
|
||||||
const MetaType& get(SizeT pos) const;
|
const MetaType& get(SizeT pos) const;
|
||||||
|
|
||||||
|
/** Get meta data array.
|
||||||
|
@return Pointer to first element of the underlying meta data array.
|
||||||
|
*/
|
||||||
const MetaType* get() const;
|
const MetaType* get() const;
|
||||||
|
|
||||||
|
/** Get range position for given meta data.
|
||||||
|
@param metaPos Meta data.
|
||||||
|
@return Position of the given meta data if it is contained by the range.
|
||||||
|
*/
|
||||||
SizeT getMeta(const MetaType& metaPos) const;
|
SizeT getMeta(const MetaType& metaPos) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -141,12 +213,21 @@ namespace CNORXZ
|
||||||
SERIALIZATION_FUNCTIONS_NOPUB;
|
SERIALIZATION_FUNCTIONS_NOPUB;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ***
|
||||||
|
Specialize RangeCast for casts to URange
|
||||||
|
@see RangeCast
|
||||||
|
*/
|
||||||
template <typename MetaType>
|
template <typename MetaType>
|
||||||
struct RangeCast<URange<MetaType>>
|
struct RangeCast<URange<MetaType>>
|
||||||
{
|
{
|
||||||
|
/** cast the range */
|
||||||
static Sptr<URange<MetaType>> func(const RangePtr& r);
|
static Sptr<URange<MetaType>> func(const RangePtr& r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Create an URange, calls URangeFactory.
|
||||||
|
@param space Meta data space to create an URange on.
|
||||||
|
@return Created range.
|
||||||
|
*/
|
||||||
template <typename MetaT>
|
template <typename MetaT>
|
||||||
RangePtr urange(const Vector<MetaT>& space);
|
RangePtr urange(const Vector<MetaT>& space);
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/xindex.h
|
@file include/ranges/xindex.h
|
||||||
@brief ...
|
@brief XIndexBase and XIndex template declaration.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -20,66 +19,145 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
/** ****
|
||||||
|
Abstract index wrapper base.
|
||||||
|
Can be used for index polymorphism.
|
||||||
|
Only use if absolutely necessary, indices should always reveal as much as possible
|
||||||
|
to the compiler!
|
||||||
|
*/
|
||||||
class XIndexBase
|
class XIndexBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//typedef DType MetaType;
|
DEFAULT_MEMBERS(XIndexBase); /**< default constructors and assignments */
|
||||||
|
|
||||||
DEFAULT_MEMBERS(XIndexBase);
|
/** Virtual default destructor */
|
||||||
virtual ~XIndexBase() = default;
|
virtual ~XIndexBase() = default;
|
||||||
|
|
||||||
|
/** Copy this index
|
||||||
|
@return Pointer to the copy.
|
||||||
|
*/
|
||||||
virtual XIndexPtr copy() const = 0;
|
virtual XIndexPtr copy() const = 0;
|
||||||
|
|
||||||
|
/** Current position.
|
||||||
|
@return Current position.
|
||||||
|
*/
|
||||||
virtual SizeT pos() const = 0;
|
virtual SizeT pos() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||||
virtual XIndexBase& operator=(SizeT lexpos) = 0;
|
virtual XIndexBase& operator=(SizeT lexpos) = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator++() */
|
||||||
virtual XIndexBase& operator++() = 0;
|
virtual XIndexBase& operator++() = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator--() */
|
||||||
virtual XIndexBase& operator--() = 0;
|
virtual XIndexBase& operator--() = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+() */
|
||||||
virtual XIndexPtr operator+(Int n) const = 0;
|
virtual XIndexPtr operator+(Int n) const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-() */
|
||||||
virtual XIndexPtr operator-(Int n) const = 0;
|
virtual XIndexPtr operator-(Int n) const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-(UIndex) */
|
||||||
virtual SizeT operator-(const XIndexBase& i) const = 0;
|
virtual SizeT operator-(const XIndexBase& i) const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+=() */
|
||||||
virtual XIndexBase& operator+=(Int n) = 0;
|
virtual XIndexBase& operator+=(Int n) = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-=() */
|
||||||
virtual XIndexBase& operator-=(Int n) = 0;
|
virtual XIndexBase& operator-=(Int n) = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lex() */
|
||||||
virtual SizeT lex() const = 0;
|
virtual SizeT lex() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::pmax() */
|
||||||
virtual UPos pmax() const = 0;
|
virtual UPos pmax() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lmax() */
|
||||||
virtual UPos lmax() const = 0;
|
virtual UPos lmax() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::id() */
|
||||||
virtual IndexId<0> id() const = 0;
|
virtual IndexId<0> id() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator*() */
|
||||||
virtual DType operator*() const = 0;
|
virtual DType operator*() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::dim() */
|
||||||
virtual SizeT dim() const = 0;
|
virtual SizeT dim() const = 0;
|
||||||
virtual RangePtr range() const = 0;
|
|
||||||
virtual UPos stepSize(const IndexId<0>& id) const = 0;
|
|
||||||
virtual RangePtr prange(const XIndexPtr& last) const = 0;
|
|
||||||
virtual Vector<SizeT> deepFormat() const = 0;
|
|
||||||
virtual Vector<SizeT> deepMax() const = 0;
|
|
||||||
virtual XIndexBase& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s) = 0;
|
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::range() */
|
||||||
|
virtual RangePtr range() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stepSize() */
|
||||||
|
virtual UPos stepSize(const IndexId<0>& id) const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stringMeta() */
|
||||||
virtual String stringMeta() const = 0;
|
virtual String stringMeta() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::meta() */
|
||||||
virtual DType meta() const = 0;
|
virtual DType meta() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::at() */
|
||||||
virtual XIndexBase& at(const DType& meta) = 0;
|
virtual XIndexBase& at(const DType& meta) = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::prange() */
|
||||||
|
virtual RangePtr prange(const XIndexPtr& last) const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepFormat() */
|
||||||
|
virtual Vector<SizeT> deepFormat() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepMax() */
|
||||||
|
virtual Vector<SizeT> deepMax() const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::reformat() */
|
||||||
|
virtual XIndexBase& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s) = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::ifor() */
|
||||||
virtual DXpr<None> ifor(const DXpr<None>& xpr, NoF&& f) const = 0;
|
virtual DXpr<None> ifor(const DXpr<None>& xpr, NoF&& f) const = 0;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::formatIsTrivial() */
|
||||||
virtual bool formatIsTrivial() const = 0;
|
virtual bool formatIsTrivial() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Sptr<XIndexBase>& operator++(Sptr<XIndexBase>& i);
|
/** ****
|
||||||
//Sptr<XIndexBase>& operator--(Sptr<XIndexBase>& i);
|
Index Wrapper.
|
||||||
|
@tparam Index Type of index to be wrapped.
|
||||||
// MultiIndex Wrapper:
|
@tparam Meta Meta data type of wrapped index.
|
||||||
|
*/
|
||||||
template <class Index, typename Meta>
|
template <class Index, typename Meta>
|
||||||
class XIndex : public XIndexBase
|
class XIndex : public XIndexBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DEFAULT_C(XIndex);
|
DEFAULT_C(XIndex); /** < default constructor. */
|
||||||
// no default copy/assignment (have to copy objects in shared ptr)
|
|
||||||
|
/** Copy constructor.
|
||||||
|
No default: have to copy objects in shared ptr.
|
||||||
|
*/
|
||||||
XIndex(const XIndex& i);
|
XIndex(const XIndex& i);
|
||||||
|
|
||||||
|
/** Move constructor.
|
||||||
|
*/
|
||||||
XIndex(XIndex&& i);
|
XIndex(XIndex&& i);
|
||||||
|
|
||||||
|
/** Copy assignment.
|
||||||
|
No default: have to copy objects in shared ptr.
|
||||||
|
*/
|
||||||
XIndex& operator=(const XIndex& i);
|
XIndex& operator=(const XIndex& i);
|
||||||
|
|
||||||
|
/** Move assignment.
|
||||||
|
*/
|
||||||
XIndex& operator=(XIndex&& i);
|
XIndex& operator=(XIndex&& i);
|
||||||
|
|
||||||
|
/** Construct.
|
||||||
|
@param i Pointer to index to be wrapped.
|
||||||
|
*/
|
||||||
XIndex(const IndexPtr<Index,Meta>& i);
|
XIndex(const IndexPtr<Index,Meta>& i);
|
||||||
|
|
||||||
|
/** Construct.
|
||||||
|
@param i Index to be wrapped.
|
||||||
|
*/
|
||||||
XIndex(const IndexInterface<Index,Meta>& i);
|
XIndex(const IndexInterface<Index,Meta>& i);
|
||||||
|
|
||||||
virtual XIndexPtr copy() const override final;
|
virtual XIndexPtr copy() const override final;
|
||||||
|
@ -104,20 +182,24 @@ namespace CNORXZ
|
||||||
virtual SizeT dim() const override final;
|
virtual SizeT dim() const override final;
|
||||||
virtual RangePtr range() const override final;
|
virtual RangePtr range() const override final;
|
||||||
virtual UPos stepSize(const IndexId<0>& id) const override final;
|
virtual UPos stepSize(const IndexId<0>& id) const override final;
|
||||||
|
virtual String stringMeta() const override final;
|
||||||
|
virtual DType meta() const override final;
|
||||||
|
virtual XIndexBase& at(const DType& meta) override final;
|
||||||
virtual RangePtr prange(const XIndexPtr& last) const override final;
|
virtual RangePtr prange(const XIndexPtr& last) const override final;
|
||||||
virtual Vector<SizeT> deepFormat() const override final;
|
virtual Vector<SizeT> deepFormat() const override final;
|
||||||
virtual Vector<SizeT> deepMax() const override final;
|
virtual Vector<SizeT> deepMax() const override final;
|
||||||
virtual XIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s) override final;
|
virtual XIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s) override final;
|
||||||
|
|
||||||
virtual String stringMeta() const override final;
|
|
||||||
virtual DType meta() const override final;
|
|
||||||
virtual XIndexBase& at(const DType& meta) override final;
|
|
||||||
|
|
||||||
virtual DXpr<None> ifor(const DXpr<None>& xpr, NoF&& f) const override final;
|
virtual DXpr<None> ifor(const DXpr<None>& xpr, NoF&& f) const override final;
|
||||||
|
|
||||||
virtual bool formatIsTrivial() const override final;
|
virtual bool formatIsTrivial() const override final;
|
||||||
|
|
||||||
|
/** Get underlying index instance.
|
||||||
|
@return Reference to index.
|
||||||
|
*/
|
||||||
Index& get();
|
Index& get();
|
||||||
|
|
||||||
|
/** Get underlying index instance (const).
|
||||||
|
@return Reference to index.
|
||||||
|
*/
|
||||||
const Index& get() const;
|
const Index& get() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -125,13 +207,28 @@ namespace CNORXZ
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Specialization: has_sub for XIndexBase.
|
||||||
|
XIndexBase can have sub-indices.
|
||||||
|
@see has_sub.
|
||||||
|
*/
|
||||||
template <>
|
template <>
|
||||||
struct has_sub<XIndexBase>
|
struct has_sub<XIndexBase>
|
||||||
{ static constexpr bool value = true; };
|
{ static constexpr bool value = true; };
|
||||||
|
|
||||||
|
/** Create XIndex pointer.
|
||||||
|
@param i Index to be wrapped.
|
||||||
|
@return Pointer to created index wrapper.
|
||||||
|
*/
|
||||||
template <class Index>
|
template <class Index>
|
||||||
inline XIndexPtr xindexPtr(const Sptr<Index>& i);
|
inline XIndexPtr xindexPtr(const Sptr<Index>& i);
|
||||||
|
|
||||||
|
/** Specialization of xindexPtr().
|
||||||
|
If input index type is already a XIndex, the corresponding pointer is just passed.
|
||||||
|
This is to avoid unwanted chains of index wrappers.
|
||||||
|
@param i Input index.
|
||||||
|
@return i.
|
||||||
|
*/
|
||||||
template <>
|
template <>
|
||||||
inline XIndexPtr xindexPtr<XIndexBase>(const Sptr<XIndexBase>& i);
|
inline XIndexPtr xindexPtr<XIndexBase>(const Sptr<XIndexBase>& i);
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/yrange.h
|
@file include/ranges/yrange.h
|
||||||
@brief ...
|
@brief YRange and YIndex declaration
|
||||||
|
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
@ -24,6 +23,13 @@
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
/** ****
|
||||||
|
Specific index for YRanges.
|
||||||
|
|
||||||
|
A YIndex is a multi-index which consists of a set of sub-indices
|
||||||
|
and a format. In the case the index is used to access data, this format
|
||||||
|
determines the linearized memory position for a given sub-index combination.
|
||||||
|
*/
|
||||||
class YIndex : public IndexInterface<YIndex,Vector<DType>>
|
class YIndex : public IndexInterface<YIndex,Vector<DType>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -32,59 +38,160 @@ namespace CNORXZ
|
||||||
typedef Vector<DType> MetaType;
|
typedef Vector<DType> MetaType;
|
||||||
|
|
||||||
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
||||||
|
|
||||||
|
/** Default constructor. */
|
||||||
YIndex() = default;
|
YIndex() = default;
|
||||||
|
|
||||||
|
/** Move constructor. */
|
||||||
YIndex(YIndex&& i) = default;
|
YIndex(YIndex&& i) = default;
|
||||||
|
|
||||||
|
/** Move assignment. */
|
||||||
YIndex& operator=(YIndex&& i) = default;
|
YIndex& operator=(YIndex&& i) = default;
|
||||||
// no defaults:
|
|
||||||
|
/** Copy constructor.
|
||||||
|
No default copy: Have to copy sub-index instances
|
||||||
|
*/
|
||||||
YIndex(const YIndex& i);
|
YIndex(const YIndex& i);
|
||||||
|
|
||||||
|
/** Copy assigment.
|
||||||
|
No default copy: Have to copy sub-index instances
|
||||||
|
*/
|
||||||
YIndex& operator=(const YIndex& i);
|
YIndex& operator=(const YIndex& i);
|
||||||
|
|
||||||
|
/** Construct from sub-index pointers.
|
||||||
|
@param is Vector of XIndex pointers.
|
||||||
|
*/
|
||||||
YIndex(const Vector<XIndexPtr>& is);
|
YIndex(const Vector<XIndexPtr>& is);
|
||||||
|
|
||||||
|
/** Construct from sub-index pointers, specify index format.
|
||||||
|
@param bs Index format (YFormat).
|
||||||
|
@param is Vector of XIndex pointers.
|
||||||
|
*/
|
||||||
YIndex(const YFormat& bs, const Vector<XIndexPtr>& is);
|
YIndex(const YFormat& bs, const Vector<XIndexPtr>& is);
|
||||||
|
|
||||||
|
/** Construct from a range and an initial lexicographic position
|
||||||
|
@param range Range to iterate over.
|
||||||
|
@param lexpos Initial lexicographic position.
|
||||||
|
*/
|
||||||
YIndex(const RangePtr& range, SizeT lexpos = 0);
|
YIndex(const RangePtr& range, SizeT lexpos = 0);
|
||||||
|
|
||||||
|
/** Construct from a range and an initial lexicographic position, specify format.
|
||||||
|
@param range Range to iterate over.
|
||||||
|
@param bs Index format.
|
||||||
|
@param lexpos Initial lexicographic position.
|
||||||
|
*/
|
||||||
YIndex(const RangePtr& range, const YFormat& bs, SizeT lexpos = 0);
|
YIndex(const RangePtr& range, const YFormat& bs, SizeT lexpos = 0);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||||
YIndex& operator=(SizeT lexpos);
|
YIndex& operator=(SizeT lexpos);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator++() */
|
||||||
YIndex& operator++();
|
YIndex& operator++();
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator--() */
|
||||||
YIndex& operator--();
|
YIndex& operator--();
|
||||||
YIndex operator+(Int n) const; // equivalent to applying n times ++
|
|
||||||
|
/** @copydoc IndexInterface::operator+() */
|
||||||
|
YIndex operator+(Int n) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-() */
|
||||||
YIndex operator-(Int n) const;
|
YIndex operator-(Int n) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-(CIndex) */
|
||||||
SizeT operator-(const YIndex& i) const;
|
SizeT operator-(const YIndex& i) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator+=() */
|
||||||
YIndex& operator+=(Int n);
|
YIndex& operator+=(Int n);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator-=() */
|
||||||
YIndex& operator-=(Int n);
|
YIndex& operator-=(Int n);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lex() */
|
||||||
SizeT lex() const;
|
SizeT lex() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::pmax() */
|
||||||
UPos pmax() const;
|
UPos pmax() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::lmax() */
|
||||||
UPos lmax() const;
|
UPos lmax() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::id() */
|
||||||
IndexId<0> id() const;
|
IndexId<0> id() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::operator*() */
|
||||||
Vector<DType> operator*() const;
|
Vector<DType> operator*() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::dim() */
|
||||||
SizeT dim() const;
|
SizeT dim() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::range() */
|
||||||
Sptr<YRange> range() const;
|
Sptr<YRange> range() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stepSize() */
|
||||||
UPos stepSize(const IndexId<0> id) const;
|
UPos stepSize(const IndexId<0> id) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::stringMeta() */
|
||||||
String stringMeta() const;
|
String stringMeta() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::meta() */
|
||||||
Vector<DType> meta() const;
|
Vector<DType> meta() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::at() */
|
||||||
YIndex& at(const Vector<DType>& meta);
|
YIndex& at(const Vector<DType>& meta);
|
||||||
|
|
||||||
DXpr<None> ifor(const DXpr<None>& xpr, NoF&& f) const;
|
/** @copydoc IndexInterface::prange() */
|
||||||
|
|
||||||
YIndex& operator()(const Sptr<YIndex>& i);
|
|
||||||
YIndex& operator()();
|
|
||||||
|
|
||||||
const DPack& pack() const;
|
|
||||||
RangePtr prange(const YIndex& last) const;
|
RangePtr prange(const YIndex& last) const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepFormat() */
|
||||||
Vector<SizeT> deepFormat() const;
|
Vector<SizeT> deepFormat() const;
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::deepMax() */
|
||||||
Vector<SizeT> deepMax() const;
|
Vector<SizeT> deepMax() const;
|
||||||
const YFormat& format() const;
|
|
||||||
const YFormat& lexFormat() const;
|
/** @copydoc IndexInterface::reformat() */
|
||||||
YIndex& setFormat(const YFormat& bs);
|
|
||||||
YIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
YIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
||||||
|
|
||||||
|
/** @copydoc IndexInterface::ifor() */
|
||||||
|
DXpr<None> ifor(const DXpr<None>& xpr, NoF&& f) const;
|
||||||
|
|
||||||
/** @copydoc IndexInterface::formatIsTrivial() */
|
/** @copydoc IndexInterface::formatIsTrivial() */
|
||||||
bool formatIsTrivial() const;
|
bool formatIsTrivial() const;
|
||||||
|
|
||||||
|
/** Replace sub-index instances.
|
||||||
|
All linearized positions are updated accordingly.
|
||||||
|
@param i Pointer to YIndex which provides the new sub-index instance
|
||||||
|
*/
|
||||||
|
YIndex& operator()(const Sptr<YIndex>& i);
|
||||||
|
|
||||||
|
/** Update all linearized positions. */
|
||||||
|
YIndex& operator()();
|
||||||
|
|
||||||
|
/** Get all sub-indices
|
||||||
|
@return Pack of sub-indices
|
||||||
|
*/
|
||||||
|
const DPack& pack() const;
|
||||||
|
|
||||||
|
/** Get index format.
|
||||||
|
@return The format.
|
||||||
|
*/
|
||||||
|
const YFormat& format() const;
|
||||||
|
|
||||||
|
/** Get lexicographic (trivial) index format.
|
||||||
|
@return The lexicographic format.
|
||||||
|
*/
|
||||||
|
const YFormat& lexFormat() const;
|
||||||
|
|
||||||
|
/** Set the index format.
|
||||||
|
@param bs The new format.
|
||||||
|
*/
|
||||||
|
YIndex& setFormat(const YFormat& bs);
|
||||||
|
|
||||||
|
/** Set position of given sub index and update total index position.
|
||||||
|
@param ind Sub-index number [0,dim()-1].
|
||||||
|
@param lex Lexicographic position to be assigned to the index.
|
||||||
|
*/
|
||||||
|
YIndex& setSub(SizeT ind, SizeT lex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline Vector<SizeT> mkFormat() const;
|
inline Vector<SizeT> mkFormat() const;
|
||||||
inline Vector<SizeT> mkLexFormat() const;
|
inline Vector<SizeT> mkLexFormat() const;
|
||||||
|
@ -107,26 +214,80 @@ namespace CNORXZ
|
||||||
UPos mLMax = 0;
|
UPos mLMax = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Specialization: YIndex is a multi-index.
|
||||||
|
@see index_is_multi
|
||||||
|
*/
|
||||||
template <>
|
template <>
|
||||||
struct index_is_multi<YIndex>
|
struct index_is_multi<YIndex>
|
||||||
{ static constexpr bool value = true; };
|
{ static constexpr bool value = true; };
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Specialization: YIndex has sub-indices.
|
||||||
|
@see has_sub
|
||||||
|
*/
|
||||||
template <>
|
template <>
|
||||||
struct has_sub<YIndex>
|
struct has_sub<YIndex>
|
||||||
{ static constexpr bool value = true; };
|
{ static constexpr bool value = true; };
|
||||||
|
|
||||||
|
/** Create YIndex from an index pack assuming a trivial index format.
|
||||||
|
@param pack Dynamic index pack.
|
||||||
|
@return The created YIndex.
|
||||||
|
*/
|
||||||
YIndex yindex(const DPack& pack);
|
YIndex yindex(const DPack& pack);
|
||||||
|
|
||||||
|
/** Create YIndex from sub-indices assuming a trivial index format.
|
||||||
|
@param is Vector of pointers to the sub-indices used in the YIndex.
|
||||||
|
@return The created YIndex.
|
||||||
|
*/
|
||||||
YIndex yindex(const Vector<XIndexPtr>& is);
|
YIndex yindex(const Vector<XIndexPtr>& is);
|
||||||
|
|
||||||
|
/** Create YIndex from an index pack assuming a trivial index format.
|
||||||
|
@param pack Dynamic index pack.
|
||||||
|
@return A shared pointer to the created YIndex.
|
||||||
|
*/
|
||||||
Sptr<YIndex> yindexPtr(const DPack& is);
|
Sptr<YIndex> yindexPtr(const DPack& is);
|
||||||
|
|
||||||
|
/** Create YIndex from sub-indices assuming a trivial index format.
|
||||||
|
@param is Vector of pointers to the sub-indices used in the YIndex.
|
||||||
|
@return A shared pointer to the created YIndex.
|
||||||
|
*/
|
||||||
Sptr<YIndex> yindexPtr(const Vector<XIndexPtr>& is);
|
Sptr<YIndex> yindexPtr(const Vector<XIndexPtr>& is);
|
||||||
|
|
||||||
|
/** Create YIndex from sub-indices.
|
||||||
|
@param is Vector of pointers to the sub-indices used in the YIndex.
|
||||||
|
@param bs Index format.
|
||||||
|
@return A shared pointer to the created YIndex.
|
||||||
|
*/
|
||||||
Sptr<YIndex> yindexPtr(const Vector<SizeT>& bs, const Vector<XIndexPtr>& is);
|
Sptr<YIndex> yindexPtr(const Vector<SizeT>& bs, const Vector<XIndexPtr>& is);
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Specific factory for YRange.
|
||||||
|
*/
|
||||||
class YRangeFactory : public RangeFactoryBase
|
class YRangeFactory : public RangeFactoryBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param rvec Vector of ranges i.e. the sub-ranges the YRange consists of
|
||||||
|
*/
|
||||||
YRangeFactory(const Vector<RangePtr>& rvec);
|
YRangeFactory(const Vector<RangePtr>& rvec);
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param rvec Vector of ranges i.e. the sub-ranges the YRange consists of (move)
|
||||||
|
*/
|
||||||
YRangeFactory(Vector<RangePtr>&& rvec);
|
YRangeFactory(Vector<RangePtr>&& rvec);
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param rvec Vector of ranges i.e. the sub-ranges the YRange consists of
|
||||||
|
@param ref Range the range to be constructed is related to
|
||||||
|
*/
|
||||||
YRangeFactory(const Vector<RangePtr>& rvec, const RangePtr& ref);
|
YRangeFactory(const Vector<RangePtr>& rvec, const RangePtr& ref);
|
||||||
|
|
||||||
|
/** Construct and setup factory.
|
||||||
|
@param rvec Vector of ranges i.e. the sub-ranges the YRange consists of (move)
|
||||||
|
@param ref Range the range to be constructed is related to
|
||||||
|
*/
|
||||||
YRangeFactory(Vector<RangePtr>&& rvec, const RangePtr& ref);
|
YRangeFactory(Vector<RangePtr>&& rvec, const RangePtr& ref);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -138,6 +299,13 @@ namespace CNORXZ
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Dynamic multi-dimensional range
|
||||||
|
|
||||||
|
Dimension and sub-range types are determined at runtime
|
||||||
|
The size of the range is given by the product of the
|
||||||
|
sizes of all sub-ranges.
|
||||||
|
*/
|
||||||
class YRange : public RangeInterface<YRange>
|
class YRange : public RangeInterface<YRange>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -169,8 +337,16 @@ namespace CNORXZ
|
||||||
SERIALIZATION_FUNCTIONS_NOPUB;
|
SERIALIZATION_FUNCTIONS_NOPUB;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Create YRange from sub-ranges.
|
||||||
|
@param rs Vector of pointers to the sub-ranges used by the YRange.
|
||||||
|
@return A shared pointer to the created YRange.
|
||||||
|
*/
|
||||||
RangePtr yrange(const Vector<RangePtr>& rs);
|
RangePtr yrange(const Vector<RangePtr>& rs);
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Specialize RangeCast for casts to YRange.
|
||||||
|
@see RangeCast
|
||||||
|
*/
|
||||||
template <>
|
template <>
|
||||||
struct RangeCast<YRange>
|
struct RangeCast<YRange>
|
||||||
{
|
{
|
||||||
|
|
|
@ -334,12 +334,13 @@ namespace CNORXZ
|
||||||
|
|
||||||
YIndex& YIndex::at(const Vector<DType>& meta)
|
YIndex& YIndex::at(const Vector<DType>& meta)
|
||||||
{
|
{
|
||||||
assert(meta.size() == mIs.size());
|
CXZ_ASSERT(meta.size() == mIs.size(), "input meta size ("
|
||||||
IB::mPos = 0;
|
<< meta.size() << ") different from expected size ("
|
||||||
|
<< mIs.size() << ")");
|
||||||
for(SizeT i = 0; i != mIs.size(); ++i){
|
for(SizeT i = 0; i != mIs.size(); ++i){
|
||||||
mIs[i]->at(meta[i]);
|
mIs[i]->at(meta[i]);
|
||||||
IB::mPos += mIs[i]->pos() * mFormat[i].val();
|
|
||||||
}
|
}
|
||||||
|
mkPos();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,9 +416,15 @@ namespace CNORXZ
|
||||||
|
|
||||||
YIndex& YIndex::reformat(const Vector<SizeT>& f, const Vector<SizeT>& s)
|
YIndex& YIndex::reformat(const Vector<SizeT>& f, const Vector<SizeT>& s)
|
||||||
{
|
{
|
||||||
CXZ_ASSERT(f.size() == s.size(), "input error: f.size() != s.size()");
|
|
||||||
// f: input format
|
// f: input format
|
||||||
// s: input sizes
|
// s: input sizes
|
||||||
|
CXZ_ASSERT(f.size() == s.size(), "input error: f.size() != s.size()");
|
||||||
|
if(f.size() == 1){
|
||||||
|
CXZ_ASSERT(s[0] == lmax().val(), "got inconsistent size; expeected "
|
||||||
|
<< lmax().val() << ", got " << s[0]);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
SizeT j = 0;
|
SizeT j = 0;
|
||||||
SizeT j0 = 0;
|
SizeT j0 = 0;
|
||||||
SizeT xi = 1;
|
SizeT xi = 1;
|
||||||
|
@ -427,9 +434,7 @@ namespace CNORXZ
|
||||||
xi *= mIs[i]->lmax().val();
|
xi *= mIs[i]->lmax().val();
|
||||||
SizeT xj = s[j];
|
SizeT xj = s[j];
|
||||||
if(xi < xj) {
|
if(xi < xj) {
|
||||||
// TODO: IMPLEMENT!!!
|
CXZ_ERROR("reformating with lower-dimensional formats is not possible; use sub-indices instead");
|
||||||
// check trivial format in this partition
|
|
||||||
CXZ_ERROR("reformating with lower-dimensional formats has not yet been implemented");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
j0 = j;
|
j0 = j;
|
||||||
|
@ -489,6 +494,19 @@ namespace CNORXZ
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
YIndex& YIndex::setSub(SizeT ind, SizeT lex)
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(ind < dim(), "got index number (" << ind << ") larger than dimension ("
|
||||||
|
<< dim() << ")");
|
||||||
|
auto& idx = mIs[ind];
|
||||||
|
CXZ_ASSERT(lex < idx->lmax().val(), "tried to set sub-index position " << lex
|
||||||
|
<< ", which is out of scope; maximum position in range is " << idx->lmax().val() );
|
||||||
|
(*idx) = lex;
|
||||||
|
(*this)();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************
|
/****************************
|
||||||
* non-member functions *
|
* non-member functions *
|
||||||
****************************/
|
****************************/
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/cnorxz_hdf5.cc.h
|
||||||
|
@brief CNORXZ HDF5 template sources header
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "h5_content_base.cc.h"
|
||||||
#include "h5_type_id.cc.h"
|
#include "h5_type_id.cc.h"
|
||||||
#include "h5_group.cc.h"
|
#include "h5_group.cc.h"
|
||||||
#include "h5_table.cc.h"
|
#include "h5_table.cc.h"
|
||||||
|
#include "h5_dataset.cc.h"
|
||||||
|
|
|
@ -1,8 +1,19 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/cnorxz_hdf5.h
|
||||||
|
@brief CNORXZ HDF5 main header
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#include "h5_content_base.h"
|
#include "h5_content_base.h"
|
||||||
#include "h5_file.h"
|
#include "h5_file.h"
|
||||||
#include "h5_group.h"
|
#include "h5_group.h"
|
||||||
#include "h5_table.h"
|
#include "h5_table.h"
|
||||||
|
#include "h5_dataset.h"
|
||||||
#include "h5_type_id.h"
|
#include "h5_type_id.h"
|
||||||
|
|
||||||
#include "cnorxz_hdf5.cc.h"
|
#include "cnorxz_hdf5.cc.h"
|
||||||
|
|
108
src/opt/hdf5/include/h5_content_base.cc.h
Normal file
108
src/opt/hdf5/include/h5_content_base.cc.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_content_base.cc.h
|
||||||
|
@brief Implementation of template member functions of ContentBase
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __cxz_h5_content_base_cc_h__
|
||||||
|
#define __cxz_h5_content_base_cc_h__
|
||||||
|
|
||||||
|
#include "h5_content_base.h"
|
||||||
|
|
||||||
|
namespace CNORXZ
|
||||||
|
{
|
||||||
|
namespace hdf5
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct CreateAttribute
|
||||||
|
{
|
||||||
|
static inline herr_t write(hid_t id, const String& name, const T& v)
|
||||||
|
{
|
||||||
|
CXZ_ERROR("type " << typeid(v).name() << " not supported (name "
|
||||||
|
<< name << ", id = " << id << ")");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct CreateAttribute<Int>
|
||||||
|
{
|
||||||
|
static inline herr_t write(hid_t id, const String& name, const Int& v)
|
||||||
|
{
|
||||||
|
const hsize_t dim = 1;
|
||||||
|
const hid_t type_id = H5Tarray_create(H5T_NATIVE_INT, 1, &dim);
|
||||||
|
const hid_t space_id = H5Screate(H5S_SCALAR);
|
||||||
|
const hid_t attr_id = H5Acreate(id, name.c_str(), type_id, space_id, H5P_DEFAULT,
|
||||||
|
H5P_DEFAULT);
|
||||||
|
const herr_t err = H5Awrite(attr_id, type_id, &v);
|
||||||
|
H5Aclose(attr_id);
|
||||||
|
H5Sclose(space_id);
|
||||||
|
H5Tclose(type_id);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct CreateAttribute<Double>
|
||||||
|
{
|
||||||
|
static inline herr_t write(hid_t id, const String& name, const Double& v)
|
||||||
|
{
|
||||||
|
const hsize_t dim = 1;
|
||||||
|
const hid_t type_id = H5Tarray_create(H5T_NATIVE_DOUBLE, 1, &dim);
|
||||||
|
const hid_t space_id = H5Screate(H5S_SCALAR);
|
||||||
|
const hid_t attr_id = H5Acreate(id, name.c_str(), type_id, space_id, H5P_DEFAULT,
|
||||||
|
H5P_DEFAULT);
|
||||||
|
const herr_t err = H5Awrite(attr_id, type_id, &v);
|
||||||
|
H5Aclose(attr_id);
|
||||||
|
H5Sclose(space_id);
|
||||||
|
H5Tclose(type_id);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct CreateAttribute<String>
|
||||||
|
{
|
||||||
|
static inline herr_t write(hid_t id, const String& name, const String& v)
|
||||||
|
{
|
||||||
|
const hsize_t len = v.size();
|
||||||
|
const hid_t type_id = H5Tcreate(H5T_STRING, len);
|
||||||
|
const hid_t space_id = H5Screate(H5S_SCALAR);
|
||||||
|
const hid_t attr_id = H5Acreate(id, name.c_str(), type_id, space_id, H5P_DEFAULT,
|
||||||
|
H5P_DEFAULT);
|
||||||
|
const herr_t err = H5Awrite(attr_id, type_id, v.c_str());
|
||||||
|
H5Aclose(attr_id);
|
||||||
|
H5Sclose(space_id);
|
||||||
|
H5Tclose(type_id);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline herr_t writeAttr(hid_t id, const String& name, const T& v)
|
||||||
|
{
|
||||||
|
return CreateAttribute<T>::write(id, name, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
ContentBase& ContentBase::addAttribute(const String& name, const T& value)
|
||||||
|
{
|
||||||
|
const herr_t err = writeAttr(mId, name, value);
|
||||||
|
CXZ_ASSERT(err >= 0, "error while writing attribute " << name);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,3 +1,13 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_content_base.h
|
||||||
|
@brief Abstract content base class declaration
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#ifndef __cxz_h5_content_base_h__
|
#ifndef __cxz_h5_content_base_h__
|
||||||
#define __cxz_h5_content_base_h__
|
#define __cxz_h5_content_base_h__
|
||||||
|
@ -10,42 +20,129 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace hdf5
|
namespace hdf5
|
||||||
{
|
{
|
||||||
|
// TODO: IO save error handling !!!
|
||||||
|
|
||||||
|
/** *****
|
||||||
|
Enum indicating the content type.
|
||||||
|
Used by ContainerBase derivates to indicate the derived type.
|
||||||
|
*/
|
||||||
enum class ContentType {
|
enum class ContentType {
|
||||||
ATTR = 1,
|
NONE = 0,
|
||||||
FILE = 2,
|
FILE = 1,
|
||||||
GROUP = 3,
|
GROUP = 2,
|
||||||
DSET = 4,
|
DSET = 3,
|
||||||
TABLE = 5,
|
TABLE = 4,
|
||||||
VALUE = 6,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Abstract base class for handling hdf5 objects.
|
||||||
|
*/
|
||||||
class ContentBase
|
class ContentBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DEFAULT_MEMBERS(ContentBase);
|
DEFAULT_MEMBERS(ContentBase); /**< Default constructors and assignments. */
|
||||||
|
|
||||||
|
/** Construct the class.
|
||||||
|
@param _name Content name.
|
||||||
|
@param _parent Parent content object. Leave null for the root object.
|
||||||
|
*/
|
||||||
ContentBase(const String& _name, const ContentBase* _parent = nullptr);
|
ContentBase(const String& _name, const ContentBase* _parent = nullptr);
|
||||||
|
|
||||||
|
/** Virtual default destructor. */
|
||||||
virtual ~ContentBase() = default;
|
virtual ~ContentBase() = default;
|
||||||
|
|
||||||
|
/** Get the content type.
|
||||||
|
@return Content type.
|
||||||
|
*/
|
||||||
virtual ContentType type() const = 0;
|
virtual ContentType type() const = 0;
|
||||||
|
|
||||||
|
/** Check if in read-only mode
|
||||||
|
@return True if read-only else false.
|
||||||
|
*/
|
||||||
virtual bool ro() const = 0;
|
virtual bool ro() const = 0;
|
||||||
|
|
||||||
|
/** Open object.
|
||||||
|
@return Reference to this object.
|
||||||
|
*/
|
||||||
virtual ContentBase& open() = 0;
|
virtual ContentBase& open() = 0;
|
||||||
|
|
||||||
|
/** Close object.
|
||||||
|
@return Reference to this object.
|
||||||
|
*/
|
||||||
virtual ContentBase& close() = 0;
|
virtual ContentBase& close() = 0;
|
||||||
|
|
||||||
|
/** Get object path.
|
||||||
|
@return Absolute hdf5 file internal path of this object.
|
||||||
|
*/
|
||||||
virtual String path() const = 0;
|
virtual String path() const = 0;
|
||||||
|
|
||||||
|
/** Get the file name.
|
||||||
|
@return Name of the hdf5 file this object is stored in.
|
||||||
|
*/
|
||||||
virtual String filename() const = 0;
|
virtual String filename() const = 0;
|
||||||
|
|
||||||
|
/** Check if group exists in the parent object.
|
||||||
|
@return True if object exists, else false.
|
||||||
|
*/
|
||||||
|
virtual bool exists() const = 0;
|
||||||
|
|
||||||
|
/** Get object name.
|
||||||
|
@return The name of this object.
|
||||||
|
*/
|
||||||
const String& name() const;
|
const String& name() const;
|
||||||
|
|
||||||
|
/** Get parent object.
|
||||||
|
@return Pointer to the parent of this object.
|
||||||
|
*/
|
||||||
const ContentBase* parent() const;
|
const ContentBase* parent() const;
|
||||||
RangePtr range() const;
|
|
||||||
|
/** Get object id.
|
||||||
|
@return hdf5 id of the h5 object maintained by this object.
|
||||||
|
*/
|
||||||
hid_t id() const;
|
hid_t id() const;
|
||||||
inline bool isOpen() const { return mId != 0; }
|
|
||||||
|
/** Check if object is open, i.e. if there is a valid hdf5 id.
|
||||||
|
@return True if object is open else false.
|
||||||
|
*/
|
||||||
|
bool isOpen() const;
|
||||||
|
|
||||||
|
/** Add attribute to this object.
|
||||||
|
@tparam T Attribute value type.
|
||||||
|
@param name Attribute name.
|
||||||
|
@param value Attribute value.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
ContentBase& addAttribute(const String& name, const T& value);
|
||||||
|
|
||||||
|
/** Get an attribute of this object.
|
||||||
|
@param name Attribute name.
|
||||||
|
@return The attribute value as DType.
|
||||||
|
*/
|
||||||
|
DType getAttribute(const String& name) const;
|
||||||
|
|
||||||
|
/** Check if attribute of given name exists in this object.
|
||||||
|
@param name Attribute name.
|
||||||
|
@return True if attribute exists else false.
|
||||||
|
*/
|
||||||
|
bool attributeExists(const String& name) const;
|
||||||
|
|
||||||
|
/** Get all attributes of this object.
|
||||||
|
@return Std map of key-value pairs.
|
||||||
|
*/
|
||||||
|
std::map<String,DType> getAttributes() const;
|
||||||
|
|
||||||
|
/** Get all attributes of this object and all its parent objects, recursively.
|
||||||
|
@return Std map of key-value pairs.
|
||||||
|
*/
|
||||||
|
std::map<String,DType> getRecursiveAttributes() const; // + all parent's attributes
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
String mName;
|
String mName; /**< Name of this object. */
|
||||||
const ContentBase* mParent = nullptr;
|
const ContentBase* mParent = nullptr; /**< Pointer to this object's parent. */
|
||||||
RangePtr mRange;
|
hid_t mId = 0; /**< hdf5 identifier of the hdf5 object handled by this object. */
|
||||||
hid_t mId = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Shortcut for a shared pointer to an abstract content object. */
|
||||||
typedef Sptr<ContentBase> ContentPtr;
|
typedef Sptr<ContentBase> ContentPtr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
113
src/opt/hdf5/include/h5_dataset.cc.h
Normal file
113
src/opt/hdf5/include/h5_dataset.cc.h
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_dataset.cc.h
|
||||||
|
@brief Implementation of template member functions of Dataset and SDataset.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __cxz_h5_dataset_cc_h__
|
||||||
|
#define __cxz_h5_dataset_cc_h__
|
||||||
|
|
||||||
|
#include "h5_dataset.h"
|
||||||
|
|
||||||
|
namespace CNORXZ
|
||||||
|
{
|
||||||
|
namespace hdf5
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
Dataset& Dataset::init(const ArrayBase<T>& data)
|
||||||
|
{
|
||||||
|
const hid_t tid = getTypeId(*data.data());
|
||||||
|
VCHECK(tid);
|
||||||
|
init(data.range(), tid);
|
||||||
|
if(data.begin().formatIsTrivial()){
|
||||||
|
Vector<hsize_t> dims(mDataRange->dim());
|
||||||
|
for(SizeT i = 0; i != dims.size(); ++i){
|
||||||
|
dims[i] = mDataRange->sub(i)->size();
|
||||||
|
}
|
||||||
|
const hid_t memspace = H5Screate_simple(dims.size(), dims.data(), NULL);
|
||||||
|
H5Dwrite(mId, mType, memspace, mFilespace, H5P_DEFAULT, data.data());
|
||||||
|
H5Sclose(memspace);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CXZ_ERROR("IMPLEMENT!!!");
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
SDataset<T>::SDataset(const String& name, const ContentBase* _parent) :
|
||||||
|
Dataset(name, _parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
MArray<T> SDataset<T>::read() const
|
||||||
|
{
|
||||||
|
Vector<hsize_t> dims(mDataRange->dim());
|
||||||
|
for(SizeT i = 0; i != dims.size(); ++i){
|
||||||
|
dims[i] = mDataRange->sub(i)->size();
|
||||||
|
}
|
||||||
|
const hid_t mem_space_id = H5Screate_simple(static_cast<hsize_t>(dims.size()),
|
||||||
|
dims.data(), nullptr);
|
||||||
|
const hid_t xfer_plist_id = H5Pcreate(H5P_DATASET_XFER);
|
||||||
|
MArray<T> out(mDataRange);
|
||||||
|
const herr_t err = H5Dread(mId, mType, mem_space_id, mFilespace, xfer_plist_id, out.data());
|
||||||
|
CXZ_ASSERT(err >= 0, "error while reading dataset '" << mName
|
||||||
|
<< "', errorcode :" << err);
|
||||||
|
H5Pclose(xfer_plist_id);
|
||||||
|
H5Sclose(mem_space_id);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
template <class I, typename M>
|
||||||
|
MArray<T> SDataset<T>::read(const IndexInterface<I,M>& beg, const IndexInterface<I,M>& end) const
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(beg.dim() == mDataRange->dim(), "got index of inconsistent dimension, got"
|
||||||
|
<< beg.dim() << ", expected " << mDataRange->dim());
|
||||||
|
const RangePtr outrange = beg.prange(end);
|
||||||
|
Vector<hsize_t> dims(outrange->dim());
|
||||||
|
for(SizeT i = 0; i != dims.size(); ++i){
|
||||||
|
dims[i] = outrange->sub(i)->size();
|
||||||
|
}
|
||||||
|
const Vector<hsize_t> fpos = mkFPos(beg);
|
||||||
|
H5Sselect_hyperslab(mFilespace, H5S_SELECT_SET, fpos.data(), NULL, dims.data(), NULL);
|
||||||
|
const hid_t mem_space_id = H5Screate_simple(static_cast<hsize_t>(dims.size()),
|
||||||
|
dims.data(), nullptr);
|
||||||
|
const hid_t xfer_plist_id = H5Pcreate(H5P_DATASET_XFER);
|
||||||
|
MArray<T> out(outrange);
|
||||||
|
const herr_t err = H5Dread(mId, mType, mem_space_id, mFilespace, xfer_plist_id, out.data());
|
||||||
|
CXZ_ASSERT(err >= 0, "error while reading dataset '" << mName
|
||||||
|
<< "', errorcode :" << err);
|
||||||
|
H5Pclose(xfer_plist_id);
|
||||||
|
H5Sclose(mem_space_id);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
template <class I, typename M>
|
||||||
|
Vector<hsize_t> SDataset<T>::mkFPos(const IndexInterface<I,M>& beg) const
|
||||||
|
{
|
||||||
|
Vector<hsize_t> fpos(beg.dim());
|
||||||
|
if constexpr(has_static_sub<I>::value){
|
||||||
|
iter<0,index_dim<I>::value> ( [&](auto i) { fpos[i] = beg.THIS().pack().get(i)->lex(); }, NoF{} );
|
||||||
|
}
|
||||||
|
else if constexpr(has_sub<I>::value){
|
||||||
|
for(SizeT i = 0; i != beg.dim(); ++i){
|
||||||
|
fpos[i] = beg.THIS().pack().get(i)->lex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fpos[0] = beg.lex();
|
||||||
|
}
|
||||||
|
return fpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
109
src/opt/hdf5/include/h5_dataset.h
Normal file
109
src/opt/hdf5/include/h5_dataset.h
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_dataset.h
|
||||||
|
@brief Dataset declaration.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __cxz_h5_dataset_h__
|
||||||
|
#define __cxz_h5_dataset_h__
|
||||||
|
|
||||||
|
#include "h5_types.h"
|
||||||
|
#include "h5_content_base.h"
|
||||||
|
|
||||||
|
namespace CNORXZ
|
||||||
|
{
|
||||||
|
namespace hdf5
|
||||||
|
{
|
||||||
|
/** ****
|
||||||
|
Class to handle hdf5 datasets.
|
||||||
|
*/
|
||||||
|
class Dataset : public ContentBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DEFAULT_MEMBERS(Dataset); /**< Default constructors and assignments. */
|
||||||
|
|
||||||
|
/** Construct the class.
|
||||||
|
@param name Dataset name.
|
||||||
|
@param _parent Parent content object.
|
||||||
|
*/
|
||||||
|
Dataset(const String& name, const ContentBase* _parent);
|
||||||
|
|
||||||
|
/** Destructor. Release all involved hdf5 ids. */
|
||||||
|
~Dataset();
|
||||||
|
|
||||||
|
virtual ContentType type() const override final;
|
||||||
|
virtual bool ro() const override final;
|
||||||
|
virtual Dataset& open() override final;
|
||||||
|
virtual Dataset& close() override final;
|
||||||
|
virtual String path() const override final;
|
||||||
|
virtual String filename() const override final;
|
||||||
|
virtual bool exists() const override final;
|
||||||
|
|
||||||
|
/** Initalize the dataset.
|
||||||
|
@param dataRange A potentially multi-dimensional range characterizing the dataset.
|
||||||
|
@param type Data type id.
|
||||||
|
*/
|
||||||
|
Dataset& init(const RangePtr& dataRange, hid_t type);
|
||||||
|
|
||||||
|
/** Initalize the dataset.
|
||||||
|
@param data Array containing the dataset.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
Dataset& init(const ArrayBase<T>& data);
|
||||||
|
|
||||||
|
/** Get the data range.
|
||||||
|
@return Pointer to the range.
|
||||||
|
*/
|
||||||
|
const RangePtr& dataRange() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
RangePtr mDataRange; /**< The data range. */
|
||||||
|
hid_t mType; /**< The data type identifier. */
|
||||||
|
hid_t mFilespace; /**< The hdf5 file space identifier. */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Class to handle hdf5 datasets, the value type is known at compile time.
|
||||||
|
@tparam T Dataset value type.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class SDataset : public Dataset
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DEFAULT_MEMBERS(SDataset); /**< Default constructors and assignments. */
|
||||||
|
|
||||||
|
/** Construct the class.
|
||||||
|
@param name Dataset name.
|
||||||
|
@param _parent Parent content object.
|
||||||
|
*/
|
||||||
|
SDataset(const String& name, const ContentBase* _parent);
|
||||||
|
|
||||||
|
/** Read the dataset.
|
||||||
|
@return Array containing the dataset values.
|
||||||
|
*/
|
||||||
|
MArray<T> read() const;
|
||||||
|
|
||||||
|
/** Read a given subset of the dataset.
|
||||||
|
The subset needs to be hypercubic.
|
||||||
|
@param beg Index indicating the begin edge of the hypercube.
|
||||||
|
@param end Index indicating the end edge of the hypercube (inclusive).
|
||||||
|
@return Array containing the dataset values.
|
||||||
|
*/
|
||||||
|
template <class I, typename M>
|
||||||
|
MArray<T> read(const IndexInterface<I,M>& beg, const IndexInterface<I,M>& end) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <class I, typename M>
|
||||||
|
Vector<hsize_t> mkFPos(const IndexInterface<I,M>& beg) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,3 +1,13 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_file.h
|
||||||
|
@brief Group declaration.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#ifndef __cxz_h5_file_h__
|
#ifndef __cxz_h5_file_h__
|
||||||
#define __cxz_h5_file_h__
|
#define __cxz_h5_file_h__
|
||||||
|
@ -10,14 +20,23 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace hdf5
|
namespace hdf5
|
||||||
{
|
{
|
||||||
// maybe introduce abstraction layer between as base for File and Group
|
/** ****
|
||||||
|
Class to handle hdf5 file objects.
|
||||||
|
Objects of this type usually serve as root object
|
||||||
|
so they don't have any parent.
|
||||||
|
*/
|
||||||
class File : public Group
|
class File : public Group
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef URange<String> RangeT;
|
DEFAULT_MEMBERS(File); /**< Default constructors and assignments. */
|
||||||
|
|
||||||
DEFAULT_MEMBERS(File);
|
/** Construct the class.
|
||||||
|
@param fname Path to the hdf5 file to be handled.
|
||||||
|
@param _ro Open in read-only mode if true, otherwise have write access.
|
||||||
|
*/
|
||||||
File(const String& fname, bool _ro = true);
|
File(const String& fname, bool _ro = true);
|
||||||
|
|
||||||
|
/** Destructor. Release all involved hdf5 ids. */
|
||||||
~File();
|
~File();
|
||||||
|
|
||||||
virtual ContentType type() const override final;
|
virtual ContentType type() const override final;
|
||||||
|
@ -26,8 +45,12 @@ namespace CNORXZ
|
||||||
virtual File& close() override final;
|
virtual File& close() override final;
|
||||||
virtual String path() const override final;
|
virtual String path() const override final;
|
||||||
virtual String filename() const override final;
|
virtual String filename() const override final;
|
||||||
|
virtual bool exists() const override final;
|
||||||
|
|
||||||
virtual Int exists() const override final;
|
/** Check if handled file is in hdf5 format.
|
||||||
|
@return True if file is in hdf5 format, else false.
|
||||||
|
*/
|
||||||
|
bool ishdf5() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mRo = true;
|
bool mRo = true;
|
||||||
|
|
|
@ -1,17 +1,50 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_group.cc.h
|
||||||
|
@brief Implementation of template member functions of Group.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#ifndef __cxz_h5_group_cc_h__
|
#ifndef __cxz_h5_group_cc_h__
|
||||||
#define __cxz_h5_group_cc_h__
|
#define __cxz_h5_group_cc_h__
|
||||||
|
|
||||||
#include "h5_group.h"
|
#include "h5_group.h"
|
||||||
|
#include "xpr/for.h"
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace hdf5
|
namespace hdf5
|
||||||
{
|
{
|
||||||
|
template <SizeT I, typename... Ts>
|
||||||
|
constexpr const auto& tget(const Tuple<Ts...>& t)
|
||||||
|
{
|
||||||
|
return std::get<sizeof...(Ts)-I-1>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <SizeT I, typename... Ts>
|
||||||
|
constexpr auto& tget(Tuple<Ts...>& t)
|
||||||
|
{
|
||||||
|
return std::get<sizeof...(Ts)-I-1>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <SizeT N, typename... Ts>
|
||||||
|
SizeT getTupleOffset(const Tuple<Ts...>& t, CSizeT<N> i)
|
||||||
|
{
|
||||||
|
const PtrId beg = reinterpret_cast<PtrId>(&t);
|
||||||
|
const PtrId pos = reinterpret_cast<PtrId>(&tget<i>(t));
|
||||||
|
return pos - beg;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Sptr<STable<Ts...>> Group::getTable(const String& name, Tuple<Ts...> proto)
|
Sptr<STable<Ts...>> Group::getTable(const String& name, Tuple<Ts...> proto)
|
||||||
{
|
{
|
||||||
auto i = this->getIndexTo(name);
|
auto i = this->getIndexTo(name);
|
||||||
|
CXZ_ASSERT((*i)->type() == ContentType::TABLE,
|
||||||
|
"element '" << name << "' is not of type TABLE");
|
||||||
auto tab = std::dynamic_pointer_cast<Table>( *i );
|
auto tab = std::dynamic_pointer_cast<Table>( *i );
|
||||||
if(tab == nullptr){
|
if(tab == nullptr){
|
||||||
auto stab = std::dynamic_pointer_cast<STable<Ts...>>(*i);
|
auto stab = std::dynamic_pointer_cast<STable<Ts...>>(*i);
|
||||||
|
@ -19,33 +52,54 @@ namespace CNORXZ
|
||||||
return stab;
|
return stab;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const RangePtr fields = tab->fields();
|
|
||||||
(*i)->close();
|
(*i)->close();
|
||||||
*i = std::make_shared<STable<Ts...>>(name, this, fields);
|
auto stab = std::make_shared<STable<Ts...>>(name, this);
|
||||||
return *i;
|
*i = stab;
|
||||||
|
return stab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Sptr<SDataset<T>> Group::getDataset(const String& name, T proto)
|
||||||
|
{
|
||||||
|
auto i = this->getIndexTo(name);
|
||||||
|
CXZ_ASSERT((*i)->type() == ContentType::DSET,
|
||||||
|
"element '" << name << "' is not of type DSET");
|
||||||
|
auto dset = std::dynamic_pointer_cast<Dataset>( *i );
|
||||||
|
if(dset == nullptr){
|
||||||
|
auto sdset = std::dynamic_pointer_cast<SDataset<T>>(*i);
|
||||||
|
CXZ_ASSERT(sdset != nullptr, "wrong format for dataset '" << name << "'");
|
||||||
|
return sdset;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(*i)->close();
|
||||||
|
auto sdset = std::make_shared<SDataset<T>>(name, this);
|
||||||
|
*i = sdset;
|
||||||
|
return sdset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Group& Group::addData(const String& name, const ArrayBase<T>& data)
|
Group& Group::addDataset(const String& name, const ArrayBase<T>& data)
|
||||||
{
|
{
|
||||||
CXZ_ASSERT(this->isOpen(), "tried to extend closed group");
|
CXZ_ASSERT(this->isOpen(), "tried to extend closed group");
|
||||||
CXZ_ERROR("not implemented!!!");
|
Vector<String> nvec({name});
|
||||||
|
mCont.extend( URangeFactory<String>( nvec ).create() );
|
||||||
|
auto ii = getIndexTo(name);
|
||||||
|
auto dset = std::make_shared<SDataset<T>>(name, this);
|
||||||
|
dset->init(data);
|
||||||
|
*ii = dset;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Group& Group::addTable(const String& name, const ArrayBase<Tuple<Ts...>>& data,
|
Group& Group::addTable(const String& name, const ArrayBase<Tuple<Ts...>>& data,
|
||||||
const Vector<String>& fnames)
|
const Arr<String,sizeof...(Ts)>& fnames)
|
||||||
{
|
{
|
||||||
CXZ_ASSERT(this->isOpen(), "tried to extend closed group");
|
CXZ_ASSERT(this->isOpen(), "tried to extend closed group");
|
||||||
Vector<String> nvec({name});
|
Vector<String> nvec({name});
|
||||||
Vector<DType> dvec({DType(name)});
|
mCont.extend( URangeFactory<String>( nvec ).create() );
|
||||||
auto extr = URangeFactory<String>( nvec ).create();
|
auto ii = getIndexTo(name);
|
||||||
mCont.extend(extr);
|
|
||||||
auto ii = mCont.begin();
|
|
||||||
ii.at(dvec); // 'at' returns YIndex&, so cannot use it inline...
|
|
||||||
auto tab = std::make_shared<STable<Ts...>>(name, this, fnames);
|
auto tab = std::make_shared<STable<Ts...>>(name, this, fnames);
|
||||||
for(auto& d: data){
|
for(auto& d: data){
|
||||||
tab->appendRecord(d);
|
tab->appendRecord(d);
|
||||||
|
@ -54,6 +108,41 @@ namespace CNORXZ
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class F>
|
||||||
|
decltype(auto) Group::iter(F&& f) const
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(isOpen(), "try to iterate over closed object");
|
||||||
|
RangePtr gr = *mCont.range()->sub().begin();
|
||||||
|
auto gi = std::make_shared<UIndex<String>>(gr);
|
||||||
|
return gi->ifor( operation(std::forward<F>(f), mCont(gi)), NoF{} );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F>
|
||||||
|
decltype(auto) Group::iterRecursive(F&& f) const
|
||||||
|
{
|
||||||
|
return iter( [&](const auto& c) {
|
||||||
|
f(c);
|
||||||
|
recursion(c, std::forward<F>(f));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F>
|
||||||
|
decltype(auto) Group::iter(F&& f)
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(isOpen(), "try to iterate over closed object");
|
||||||
|
RangePtr gr = *mCont.range()->sub().begin();
|
||||||
|
auto gi = std::make_shared<UIndex<String>>(gr);
|
||||||
|
return gi->ifor( operation(std::forward<F>(f), mCont(gi)), NoF{} );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F>
|
||||||
|
decltype(auto) Group::iterRecursive(F&& f)
|
||||||
|
{
|
||||||
|
return iter( [&](const auto& c) {
|
||||||
|
f(c);
|
||||||
|
recursion(c, std::forward<F>(f));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_group.h
|
||||||
|
@brief Group declaration.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#ifndef __cxz_h5_group_h__
|
#ifndef __cxz_h5_group_h__
|
||||||
#define __cxz_h5_group_h__
|
#define __cxz_h5_group_h__
|
||||||
|
@ -9,11 +19,21 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace hdf5
|
namespace hdf5
|
||||||
{
|
{
|
||||||
|
/** ****
|
||||||
|
Class to handle hdf5 groups.
|
||||||
|
*/
|
||||||
class Group : public ContentBase
|
class Group : public ContentBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DEFAULT_MEMBERS(Group);
|
DEFAULT_MEMBERS(Group); /**< Default constructors and assignments. */
|
||||||
|
|
||||||
|
/** Construct the class.
|
||||||
|
@param gname Group name.
|
||||||
|
@param _parent Parent content object.
|
||||||
|
*/
|
||||||
Group(const String& gname, const ContentBase* _parent);
|
Group(const String& gname, const ContentBase* _parent);
|
||||||
|
|
||||||
|
/** Destructor. Release all involved hdf5 ids. */
|
||||||
~Group();
|
~Group();
|
||||||
|
|
||||||
virtual ContentType type() const override;
|
virtual ContentType type() const override;
|
||||||
|
@ -22,31 +42,138 @@ namespace CNORXZ
|
||||||
virtual Group& close() override;
|
virtual Group& close() override;
|
||||||
virtual String path() const override;
|
virtual String path() const override;
|
||||||
virtual String filename() const override;
|
virtual String filename() const override;
|
||||||
|
virtual bool exists() const override;
|
||||||
|
|
||||||
virtual Int exists() const;
|
/** Get object contained by this group.
|
||||||
|
@param name Object name.
|
||||||
|
@return Pointer to the object.
|
||||||
|
*/
|
||||||
const ContentPtr& get(const String& name) const;
|
const ContentPtr& get(const String& name) const;
|
||||||
|
|
||||||
|
/** Get object contained by this group as group.
|
||||||
|
Checks if the object is a group.
|
||||||
|
@param name Group name.
|
||||||
|
@return Pointer to the group.
|
||||||
|
*/
|
||||||
Sptr<Group> getGroup(const String& name) const;
|
Sptr<Group> getGroup(const String& name) const;
|
||||||
|
|
||||||
|
/** Get object contained by this group as table.
|
||||||
|
Checks if the object is a table.
|
||||||
|
@param name Table name.
|
||||||
|
@return Pointer to the table.
|
||||||
|
*/
|
||||||
Sptr<Table> getTable(const String& name) const;
|
Sptr<Table> getTable(const String& name) const;
|
||||||
|
|
||||||
|
/** Get object contained by this group as dataset.
|
||||||
|
Checks if the object is a table.
|
||||||
|
@param name Dataset name.
|
||||||
|
@return Pointer to the dataset.
|
||||||
|
*/
|
||||||
|
Sptr<Dataset> getDataset(const String& name) const;
|
||||||
|
|
||||||
|
/** Get object contained by this group as table for given value type.
|
||||||
|
Checks if the object is a table.
|
||||||
|
@tparam Ts Table entry types.
|
||||||
|
@param name Table name.
|
||||||
|
@param proto Empty prototype (template argument resolution).
|
||||||
|
@return Pointer to the table.
|
||||||
|
*/
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Sptr<STable<Ts...>> getTable(const String& name, Tuple<Ts...> proto);
|
Sptr<STable<Ts...>> getTable(const String& name, Tuple<Ts...> proto);
|
||||||
|
|
||||||
|
/** Get object contained by this group as dataset for given value type.
|
||||||
|
Checks if the object is a dataset.
|
||||||
|
@tparam T Dataset value type.
|
||||||
|
@param name Dataset name.
|
||||||
|
@param proto Empty prototype (template argument resolution).
|
||||||
|
@return Pointer to the dataset.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
Sptr<SDataset<T>> getDataset(const String& name, T proto);
|
||||||
|
|
||||||
|
/** Get objects contained by this group.
|
||||||
|
@returns MArray of object pointers.
|
||||||
|
*/
|
||||||
const MArray<ContentPtr>& get() const;
|
const MArray<ContentPtr>& get() const;
|
||||||
|
|
||||||
|
/** Add a new group to this group.
|
||||||
|
@param name Name of the created group.
|
||||||
|
*/
|
||||||
Group& addGroup(const String& name);
|
Group& addGroup(const String& name);
|
||||||
|
|
||||||
template <typename T>
|
/** Add a new table to this group.
|
||||||
Group& addData(const String& name, const ArrayBase<T>& data);
|
@tparam Ts Table element types.
|
||||||
|
@param name Name of the created table.
|
||||||
|
@param data Table data.
|
||||||
|
@param fnames Table field names.
|
||||||
|
*/
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Group& addTable(const String& name, const ArrayBase<Tuple<Ts...>>& data,
|
Group& addTable(const String& name, const ArrayBase<Tuple<Ts...>>& data,
|
||||||
const Vector<String>& fnames);
|
const Arr<String,sizeof...(Ts)>& fnames);
|
||||||
|
|
||||||
|
/** Add a new dataset to this group.
|
||||||
|
@tparam T Value type.
|
||||||
|
@param name Name of the created dataset.
|
||||||
|
@param data Dataset data.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
Group& addDataset(const String& name, const ArrayBase<T>& data);
|
||||||
|
|
||||||
|
/** Iterate over all group elements (const).
|
||||||
|
@param f function object to be executed on each group element.
|
||||||
|
*/
|
||||||
|
template <class F>
|
||||||
|
decltype(auto) iter(F&& f) const;
|
||||||
|
|
||||||
|
/** Iterate recursively over all group elements (const).
|
||||||
|
@param f function object to be executed on each group element.
|
||||||
|
*/
|
||||||
|
template <class F>
|
||||||
|
decltype(auto) iterRecursive(F&& f) const;
|
||||||
|
|
||||||
|
/** Iterate over all group elements.
|
||||||
|
@param f function object to be executed on each group element.
|
||||||
|
*/
|
||||||
|
template <class F>
|
||||||
|
decltype(auto) iter(F&& f);
|
||||||
|
|
||||||
|
/** Iterate recursively over all group elements.
|
||||||
|
@param f function object to be executed on each group element.
|
||||||
|
*/
|
||||||
|
template <class F>
|
||||||
|
decltype(auto) iterRecursive(F&& f);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MArray<ContentPtr> mCont;
|
|
||||||
|
|
||||||
|
MArray<ContentPtr> mCont; /**< Group elements. */
|
||||||
|
|
||||||
|
/** Recursion helper functon.
|
||||||
|
@param c Group element.
|
||||||
|
@param f Function to be executed.
|
||||||
|
*/
|
||||||
|
template <typename C, class F>
|
||||||
|
static void recursion(const C& c, F&& f)
|
||||||
|
{
|
||||||
|
if(c->type() == ContentType::GROUP){
|
||||||
|
auto cx = std::dynamic_pointer_cast<Group>(c);
|
||||||
|
cx->open();
|
||||||
|
if(cx->get().range() != nullptr){
|
||||||
|
cx->iterRecursive(std::forward<F>(f))();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Setup group content. */
|
||||||
void mkCont();
|
void mkCont();
|
||||||
|
|
||||||
|
/** Get index to requested group element (const).
|
||||||
|
@param name Element name.
|
||||||
|
*/
|
||||||
AIndex<ContentPtr> getIndexTo(const String& name) const;
|
AIndex<ContentPtr> getIndexTo(const String& name) const;
|
||||||
|
|
||||||
|
/** Get index to requested group element.
|
||||||
|
@param name Element name.
|
||||||
|
*/
|
||||||
BIndex<ContentPtr> getIndexTo(const String& name);
|
BIndex<ContentPtr> getIndexTo(const String& name);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_table.cc.h
|
||||||
|
@brief Implementation of template member functions of Table and STable.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#ifndef __cxz_h5_table_cc_h__
|
#ifndef __cxz_h5_table_cc_h__
|
||||||
#define __cxz_h5_table_cc_h__
|
#define __cxz_h5_table_cc_h__
|
||||||
|
@ -9,6 +19,16 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace hdf5
|
namespace hdf5
|
||||||
{
|
{
|
||||||
|
template <class F>
|
||||||
|
decltype(auto) Table::iterRecords(F&& f) const
|
||||||
|
{
|
||||||
|
auto ri = std::make_shared<CIndex>(mRecords);
|
||||||
|
return ri->ifor
|
||||||
|
( operation( std::forward<F>(f),
|
||||||
|
operation( [&](const SizeT pos) { return readRecord(pos); } ,
|
||||||
|
xpr(ri) ) ), NoF{} );
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
template <class F>
|
template <class F>
|
||||||
decltype(auto) STable<Ts...>::iterRecords(F&& f) const
|
decltype(auto) STable<Ts...>::iterRecords(F&& f) const
|
||||||
|
@ -18,51 +38,69 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
STable<Ts...>::STable(const String& name, const ContentBase* _parent,
|
STable<Ts...>::STable(const String& name, const ContentBase* _parent) :
|
||||||
const Vector<String>& fnames) :
|
|
||||||
Table(name, _parent)
|
Table(name, _parent)
|
||||||
{
|
{
|
||||||
constexpr SizeT N = sizeof...(Ts);
|
constexpr SizeT N = sizeof...(Ts);
|
||||||
if(mFields == nullptr){
|
if(mFields != nullptr){
|
||||||
CXZ_ASSERT(fnames.size() != 0, "field names have to be initialized");
|
|
||||||
Vector<FieldID> fields(fnames.size());
|
|
||||||
for(SizeT i = 0; i != fields.size(); ++i){
|
|
||||||
fields[i].first = i;
|
|
||||||
fields[i].second = fnames[i];
|
|
||||||
}
|
|
||||||
mFields = URangeFactory<FieldID>(fields).create();
|
|
||||||
}
|
|
||||||
CXZ_ASSERT(mFields->size() == sizeof...(Ts), "expected tuple of size = " << mFields->size()
|
|
||||||
<< ", got: " << sizeof...(Ts));
|
|
||||||
|
|
||||||
Tuple<Ts...> x;
|
CXZ_ASSERT(mFields->size() == N, "expected tuple of size = " << mFields->size()
|
||||||
if(mRecords == nullptr) {
|
<< ", got: " << N);
|
||||||
mOffsets = MArray<SizeT>( mFields, iter<0,N>
|
Tuple<Ts...> x;
|
||||||
( [&](auto i) { return getTupleOffset(x, i); },
|
|
||||||
[](const auto&... e) { return Vector<SizeT>({e...}); }) );
|
|
||||||
mSizes = MArray<SizeT>( mFields, iter<0,N>
|
|
||||||
( [&](auto i) { return sizeof(std::get<i>(x)); },
|
|
||||||
[](const auto&... e) { return Vector<SizeT>({e...}); }) );
|
|
||||||
mTypes = MArray<hid_t>( mFields, iter<0,N>
|
|
||||||
( [&](auto i) { return getTypeId(std::get<i>(x)); },
|
|
||||||
[](const auto&... e) { return Vector<hid_t>({e...}); }) );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
iter<0,N>( [&](auto i) { CXZ_ASSERT
|
iter<0,N>( [&](auto i) { CXZ_ASSERT
|
||||||
( getTupleOffset(x, i) == mOffsets.data()[i],
|
( getTupleOffset(x, i) == mOffsets.data()[i],
|
||||||
"wrong offset for field " << i << ": " << getTupleOffset(x, i)
|
"wrong offset for field " << i << ": " << getTupleOffset(x, i)
|
||||||
<< " vs " << mOffsets.data()[i] ); }, NoF{} );
|
<< " vs " << mOffsets.data()[i] ); }, NoF{} );
|
||||||
iter<0,N>( [&](auto i) { CXZ_ASSERT
|
iter<0,N>( [&](auto i) { CXZ_ASSERT
|
||||||
( sizeof(std::get<i>(x)) == mSizes.data()[i],
|
( sizeof(tget<i>(x)) == mSizes.data()[i],
|
||||||
"wrong size for field " << i << ": " << sizeof(std::get<i>(x))
|
"wrong size for field " << i << ": " << sizeof(tget<i>(x))
|
||||||
<< " vs " << mSizes.data()[i] ); }, NoF{} );
|
<< " vs " << mSizes.data()[i] ); }, NoF{} );
|
||||||
iter<0,N>( [&](auto i) { CXZ_ASSERT
|
iter<0,N>( [&](auto i) { CXZ_ASSERT
|
||||||
( getTypeId(std::get<i>(x)) == mTypes.data()[i],
|
( H5Tget_class(getTypeId(tget<i>(x))) == mTypes.data()[i],
|
||||||
"wrong type for field " << i << ": " << getTypeId(std::get<i>(x))
|
"wrong type for field " << i
|
||||||
|
<< ": " << H5Tget_class(getTypeId(tget<i>(x)))
|
||||||
<< " vs " << mTypes.data()[i] ); }, NoF{} );
|
<< " vs " << mTypes.data()[i] ); }, NoF{} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
STable<Ts...>::STable(const String& name, const ContentBase* _parent,
|
||||||
|
const Arr<String,sizeof...(Ts)>& fnames) :
|
||||||
|
Table(name, _parent)
|
||||||
|
{
|
||||||
|
initFields(fnames);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
STable<Ts...>& STable<Ts...>::initFields(const Arr<String,sizeof...(Ts)>& fnames)
|
||||||
|
{
|
||||||
|
constexpr SizeT N = sizeof...(Ts);
|
||||||
|
CXZ_ASSERT(mFields == nullptr and mRecords == nullptr,
|
||||||
|
"tried to initialize an existing table");
|
||||||
|
|
||||||
|
Vector<FieldID> fields(fnames.size());
|
||||||
|
for(SizeT i = 0; i != fields.size(); ++i){
|
||||||
|
fields[i].first = i;
|
||||||
|
fields[i].second = fnames[i];
|
||||||
|
}
|
||||||
|
mFields = URangeFactory<FieldID>(fields).create();
|
||||||
|
|
||||||
|
Tuple<Ts...> x;
|
||||||
|
mOffsets = MArray<SizeT>
|
||||||
|
( mFields, iter<0,N>
|
||||||
|
( [&](auto i) { return getTupleOffset(x, i); },
|
||||||
|
[](const auto&... e) { return Vector<SizeT>({e...}); }) );
|
||||||
|
mSizes = MArray<SizeT>
|
||||||
|
( mFields, iter<0,N>
|
||||||
|
( [&](auto i) { return sizeof(tget<i>(x)); },
|
||||||
|
[](const auto&... e) { return Vector<SizeT>({e...}); }) );
|
||||||
|
mTypes = MArray<hid_t>
|
||||||
|
( mFields, iter<0,N>
|
||||||
|
( [&](auto i) { return getTypeId(tget<i>(x)); },
|
||||||
|
[](const auto&... e) { return Vector<hid_t>({e...}); }) );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
STable<Ts...>& STable<Ts...>::appendRecord(const Tuple<Ts...>& t)
|
STable<Ts...>& STable<Ts...>::appendRecord(const Tuple<Ts...>& t)
|
||||||
{
|
{
|
||||||
|
@ -71,10 +109,20 @@ namespace CNORXZ
|
||||||
initTable(1, &t, sizeof(t), sizeof(t));
|
initTable(1, &t, sizeof(t), sizeof(t));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Table::appendRecord(1, &t, sizeof(t));
|
Table::appendRecords(1, &t);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
MArray<Tuple<Ts...>> STable<Ts...>::read() const
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(isOpen(), "attempt to read table that has not been opened");
|
||||||
|
MArray<Tuple<Ts...>> out(mRecords);
|
||||||
|
H5TBread_table(mParent->id(), mName.c_str(), mTypesize, mOffsets.data(),
|
||||||
|
mSizes.data(), out.data());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_table.h
|
||||||
|
@brief Table declaration.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#ifndef __cxz_h5_table_h__
|
#ifndef __cxz_h5_table_h__
|
||||||
#define __cxz_h5_table_h__
|
#define __cxz_h5_table_h__
|
||||||
|
@ -9,13 +19,23 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace hdf5
|
namespace hdf5
|
||||||
{
|
{
|
||||||
|
/** ****
|
||||||
|
Class to handle hdf5 tables.
|
||||||
|
*/
|
||||||
class Table : public ContentBase
|
class Table : public ContentBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::pair<SizeT,String> FieldID;
|
typedef std::pair<SizeT,String> FieldID; /**< Meta data type of fields range. */
|
||||||
|
|
||||||
DEFAULT_MEMBERS(Table);
|
DEFAULT_MEMBERS(Table); /**< Default constructors and assignments. */
|
||||||
|
|
||||||
|
/** Construct the class.
|
||||||
|
@param name Table name.
|
||||||
|
@param _parent Parent content object.
|
||||||
|
*/
|
||||||
Table(const String& name, const ContentBase* _parent);
|
Table(const String& name, const ContentBase* _parent);
|
||||||
|
|
||||||
|
/** Destructor. Release all involved hdf5 ids. */
|
||||||
~Table();
|
~Table();
|
||||||
|
|
||||||
virtual ContentType type() const override final;
|
virtual ContentType type() const override final;
|
||||||
|
@ -24,36 +44,130 @@ namespace CNORXZ
|
||||||
virtual Table& close() override final;
|
virtual Table& close() override final;
|
||||||
virtual String path() const override final;
|
virtual String path() const override final;
|
||||||
virtual String filename() const override final;
|
virtual String filename() const override final;
|
||||||
|
virtual bool exists() const override final;
|
||||||
|
|
||||||
|
/** Ininitialize table field names.
|
||||||
|
@param fnames Table field names.
|
||||||
|
*/
|
||||||
Table& initFieldNames(const Vector<String>& fnames);
|
Table& initFieldNames(const Vector<String>& fnames);
|
||||||
|
|
||||||
|
/** Initialize the table.
|
||||||
|
@param n Number of records (rows).
|
||||||
|
@param data Table data.
|
||||||
|
@param dsize Record type size.
|
||||||
|
@param chunk_size Chunk size.
|
||||||
|
*/
|
||||||
Table& initTable(SizeT n, const void* data, SizeT dsize, SizeT chunk_size);
|
Table& initTable(SizeT n, const void* data, SizeT dsize, SizeT chunk_size);
|
||||||
Table& appendRecord(SizeT n, const void* data, SizeT dsize);
|
|
||||||
Table& readRecord(SizeT pos, SizeT n, char* data);
|
/** Append records to the table.
|
||||||
|
@param n Number of records to append.
|
||||||
|
@param data Records data.
|
||||||
|
*/
|
||||||
|
Table& appendRecords(SizeT n, const void* data);
|
||||||
|
|
||||||
|
/** Read records.
|
||||||
|
@param pos Number of first record to read.
|
||||||
|
@param n Number of records to read.
|
||||||
|
@param data Target pointer.
|
||||||
|
*/
|
||||||
|
Table& readRecords(SizeT pos, SizeT n, char* data);
|
||||||
|
|
||||||
|
/** Read record.
|
||||||
|
@param pos Number of the record to be read.
|
||||||
|
@return DType array with containing the record data.
|
||||||
|
*/
|
||||||
|
MArray<DType> readRecord(SizeT pos) const;
|
||||||
|
|
||||||
|
/** Read table.
|
||||||
|
@return DType array containing the table data.
|
||||||
|
*/
|
||||||
|
MArray<DType> read() const;
|
||||||
|
|
||||||
|
/** Iterate over table records.
|
||||||
|
@param f function object to be executed on each table record.
|
||||||
|
*/
|
||||||
|
template <class F>
|
||||||
|
decltype(auto) iterRecords(F&& f) const;
|
||||||
|
|
||||||
|
/** Get fields range.
|
||||||
|
@return Pointer to the range.
|
||||||
|
*/
|
||||||
const RangePtr& fields() const;
|
const RangePtr& fields() const;
|
||||||
|
|
||||||
|
/** Get records range.
|
||||||
|
@return Pointer to the range.
|
||||||
|
*/
|
||||||
const RangePtr& records() const;
|
const RangePtr& records() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RangePtr mRecords;
|
RangePtr mRecords; /**< Records range. */
|
||||||
RangePtr mFields; // -> FIndex (position -> offset)
|
RangePtr mFields; /**< Fields range. */ // -> FIndex (position -> offset)
|
||||||
MArray<SizeT> mSizes;
|
MArray<SizeT> mSizes; /**< Field element type sizes. */
|
||||||
MArray<SizeT> mOffsets;
|
MArray<SizeT> mOffsets; /**< Field element offsets. */
|
||||||
MArray<hid_t> mTypes;
|
MArray<hid_t> mTypes; /**< Field element type ids. */
|
||||||
hid_t mType = 0;
|
hid_t mType = 0; /**< Record type id. */
|
||||||
|
SizeT mTypesize = 0; /**< Record type size. */
|
||||||
|
MArray<std::function<DType(const char*)>> mInterpret; /**< Field element type interpreting functions. */
|
||||||
|
|
||||||
|
void mkTypes(); /**< Type setup function. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ****
|
||||||
|
Class to handle hdf5 tables, the record type is known at compile time.
|
||||||
|
The records are accessed by a std tuple.
|
||||||
|
Caution: The ordering of the record entries is fixed by their memory location.
|
||||||
|
The std tuple has a reverse ordering w.r.t. the memory location, i.e. a record
|
||||||
|
with element types T1-T2-T3 (memory ordering) and field names "T1", "T2", "T3",
|
||||||
|
requires template argumens <T3,T2,T1>.
|
||||||
|
@tparam Ts Record element types.
|
||||||
|
*/
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
class STable : public Table
|
class STable : public Table
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DEFAULT_MEMBERS(STable);
|
DEFAULT_MEMBERS(STable); /**< Default constructors and assignments. */
|
||||||
STable(const String& name, const ContentBase* _parent, const Vector<String>& fnames);
|
|
||||||
|
|
||||||
|
/** Construct the class.
|
||||||
|
@param name Table name.
|
||||||
|
@param _parent Parent content object.
|
||||||
|
*/
|
||||||
|
STable(const String& name, const ContentBase* _parent);
|
||||||
|
|
||||||
|
/** Construct the class.
|
||||||
|
@param name Table name.
|
||||||
|
@param _parent Parent content object.
|
||||||
|
@param fnames Field names.
|
||||||
|
*/
|
||||||
|
STable(const String& name, const ContentBase* _parent,
|
||||||
|
const Arr<String,sizeof...(Ts)>& fnames);
|
||||||
|
|
||||||
|
/** Ininitialize and setup table fields.
|
||||||
|
@param fnames Table field names.
|
||||||
|
*/
|
||||||
|
STable& initFields(const Arr<String,sizeof...(Ts)>& fnames);
|
||||||
|
|
||||||
|
/** Append record to the table.
|
||||||
|
@param t Tuple containing the record entries.
|
||||||
|
*/
|
||||||
STable& appendRecord(const Tuple<Ts...>& t);
|
STable& appendRecord(const Tuple<Ts...>& t);
|
||||||
|
|
||||||
|
/** Append records to the table.
|
||||||
|
@param t Array of tuples containing the records.
|
||||||
|
*/
|
||||||
STable& appendRecord(const MArray<Tuple<Ts...>>& t);
|
STable& appendRecord(const MArray<Tuple<Ts...>>& t);
|
||||||
|
|
||||||
|
/** Read the table.
|
||||||
|
@return Array of tuples containing the records.
|
||||||
|
*/
|
||||||
|
MArray<Tuple<Ts...>> read() const;
|
||||||
|
|
||||||
|
/** Iterate over all table records.
|
||||||
|
@param f Function object to be executed on each record.
|
||||||
|
*/
|
||||||
template <class F>
|
template <class F>
|
||||||
decltype(auto) iterRecords(F&& f) const;
|
decltype(auto) iterRecords(F&& f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_type_id.h
|
||||||
|
@brief TypeId template implementation.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#ifndef __cxz_h5_type_id_cc_h__
|
#ifndef __cxz_h5_type_id_cc_h__
|
||||||
#define __cxz_h5_type_id_cc_h__
|
#define __cxz_h5_type_id_cc_h__
|
||||||
|
@ -8,17 +18,9 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace hdf5
|
namespace hdf5
|
||||||
{
|
{
|
||||||
template <SizeT N, typename... Ts>
|
/*============+
|
||||||
SizeT getTupleOffset(const Tuple<Ts...>& t, CSizeT<N> i)
|
| TypeId |
|
||||||
{
|
+============*/
|
||||||
const PtrId beg = reinterpret_cast<PtrId>(&t);
|
|
||||||
const PtrId pos = reinterpret_cast<PtrId>(&std::get<i>(t));
|
|
||||||
return pos - beg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************
|
|
||||||
* TypeId *
|
|
||||||
**************/
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline hid_t TypeId<T>::get()
|
inline hid_t TypeId<T>::get()
|
||||||
|
@ -28,17 +30,17 @@ namespace CNORXZ
|
||||||
|
|
||||||
inline hid_t TypeId<SizeT>::get()
|
inline hid_t TypeId<SizeT>::get()
|
||||||
{
|
{
|
||||||
return H5T_NATIVE_ULONG;
|
return H5Tcopy( H5T_NATIVE_ULONG );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hid_t TypeId<Int>::get()
|
inline hid_t TypeId<Int>::get()
|
||||||
{
|
{
|
||||||
return H5T_NATIVE_INT;
|
return H5Tcopy( H5T_NATIVE_INT );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hid_t TypeId<Double>::get()
|
inline hid_t TypeId<Double>::get()
|
||||||
{
|
{
|
||||||
return H5T_NATIVE_DOUBLE;
|
return H5Tcopy( H5T_NATIVE_DOUBLE );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, SizeT N>
|
||||||
|
@ -48,9 +50,9 @@ namespace CNORXZ
|
||||||
return arrtype;
|
return arrtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************
|
/*===============+
|
||||||
* getTypeId *
|
| getTypeId |
|
||||||
*****************/
|
+===============*/
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
hid_t getTypeId(T x)
|
hid_t getTypeId(T x)
|
||||||
|
|
|
@ -1,37 +1,74 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/h5_type_id.h
|
||||||
|
@brief TypeId template declaration.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#ifndef __cxz_h5_type_id_h__
|
#ifndef __cxz_h5_type_id_h__
|
||||||
#define __cxz_h5_type_id_h__
|
#define __cxz_h5_type_id_h__
|
||||||
|
|
||||||
|
#include "base/types.h"
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace hdf5
|
namespace hdf5
|
||||||
{
|
{
|
||||||
template <SizeT N, typename... Ts>
|
/** ****
|
||||||
SizeT getTupleOffset(const Tuple<Ts...>& t, CSizeT<N> i);
|
Get a valid hdf5 id for a given type.
|
||||||
|
Return 0 if not implemented.
|
||||||
/**************
|
@tparam T The type.
|
||||||
* TypeId *
|
*/
|
||||||
**************/
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TypeId { static inline hid_t get(); };
|
struct TypeId
|
||||||
|
{
|
||||||
|
/** Get the type id. */
|
||||||
|
static inline hid_t get();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Specialization of TypeId for SizeT. */
|
||||||
template <>
|
template <>
|
||||||
struct TypeId<SizeT> { static inline hid_t get(); };
|
struct TypeId<SizeT>
|
||||||
|
{
|
||||||
|
/** Get the type id for SizeT. */
|
||||||
|
static inline hid_t get();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Specialization of TypeId for Int. */
|
||||||
template <>
|
template <>
|
||||||
struct TypeId<Int> { static inline hid_t get(); };
|
struct TypeId<Int>
|
||||||
|
{
|
||||||
|
/** Get the type id for Int. */
|
||||||
|
static inline hid_t get();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Specialization of TypeId for Double. */
|
||||||
template <>
|
template <>
|
||||||
struct TypeId<Double> { static inline hid_t get(); };
|
struct TypeId<Double>
|
||||||
|
{
|
||||||
|
/** Get the type id for Double. */
|
||||||
|
static inline hid_t get();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Specialization of TypeId for an array
|
||||||
|
@tparam T Element type.
|
||||||
|
@tparam N Array size.
|
||||||
|
*/
|
||||||
template <typename T, SizeT N>
|
template <typename T, SizeT N>
|
||||||
struct TypeId<Arr<T,N>> { static inline hid_t get(); };
|
struct TypeId<Arr<T,N>>
|
||||||
|
{
|
||||||
/*****************
|
/** Get the type id for the given array. */
|
||||||
* getTypeId *
|
static inline hid_t get();
|
||||||
*****************/
|
};
|
||||||
|
|
||||||
|
/** Wrapper function for TypeId::get()
|
||||||
|
@param Variable of given type.
|
||||||
|
@return A type id of the input variable's type.
|
||||||
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
hid_t getTypeId(T x);
|
hid_t getTypeId(T x);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/include/types.h
|
||||||
|
@brief Declaration of hdf5 related library types
|
||||||
|
|
||||||
|
This file contains the declaration of all hdf5 related library types
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#ifndef __h5_types_h__
|
#ifndef __h5_types_h__
|
||||||
#define __h5_types_h__
|
#define __h5_types_h__
|
||||||
|
@ -22,6 +34,13 @@ namespace CNORXZ
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
class STable;
|
class STable;
|
||||||
|
|
||||||
|
// definition -> h5_dataset.h
|
||||||
|
class Dataset;
|
||||||
|
|
||||||
|
// definition -> h5_dataset.h
|
||||||
|
template <typename T>
|
||||||
|
class SDataset;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ set(libcnorxzhdf5_a_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/h5_file.cc
|
${CMAKE_CURRENT_SOURCE_DIR}/h5_file.cc
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/h5_group.cc
|
${CMAKE_CURRENT_SOURCE_DIR}/h5_group.cc
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/h5_table.cc
|
${CMAKE_CURRENT_SOURCE_DIR}/h5_table.cc
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/h5_dataset.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(cnorxzhdf5_obj OBJECT
|
add_library(cnorxzhdf5_obj OBJECT
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/hdf5/lib/h5_content_base.cc
|
||||||
|
@brief Content base member function implementation.
|
||||||
|
|
||||||
|
Implementation of all non-virtual member functions of ContentBase.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
#include "h5_content_base.h"
|
#include "h5_content_base.h"
|
||||||
|
|
||||||
|
@ -19,14 +31,121 @@ namespace CNORXZ
|
||||||
return mParent;
|
return mParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
RangePtr ContentBase::range() const
|
|
||||||
{
|
|
||||||
return mRange;
|
|
||||||
}
|
|
||||||
|
|
||||||
hid_t ContentBase::id() const
|
hid_t ContentBase::id() const
|
||||||
{
|
{
|
||||||
return mId;
|
return mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ContentBase::isOpen() const
|
||||||
|
{
|
||||||
|
return mId != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DType ContentBase::getAttribute(const String& name) const
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(attributeExists(name), "no attribute with name '" << name
|
||||||
|
<< "' in object " << mName);
|
||||||
|
const hid_t attr = H5Aopen(mId, name.c_str(), H5P_DEFAULT);
|
||||||
|
CXZ_ASSERT(attr != H5I_INVALID_HID, "error while reading attribute " << name);
|
||||||
|
const hid_t atype_id = H5Aget_type(attr);
|
||||||
|
CXZ_ASSERT(atype_id != H5I_INVALID_HID,
|
||||||
|
"error while determining type of attribute " << name);
|
||||||
|
|
||||||
|
const H5T_class_t tc = H5Tget_class(atype_id);
|
||||||
|
DType o;
|
||||||
|
switch(tc){
|
||||||
|
case H5T_INTEGER: {
|
||||||
|
Int v;
|
||||||
|
H5Aread(attr, atype_id, &v);
|
||||||
|
o = DType(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case H5T_FLOAT: {
|
||||||
|
Double v;
|
||||||
|
H5Aread(attr, atype_id, &v);
|
||||||
|
o = DType(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case H5T_STRING: {
|
||||||
|
const SizeT asize = H5Tget_size(atype_id);
|
||||||
|
Vector<char> v(asize+1);
|
||||||
|
H5Aread(attr, atype_id, v.data());
|
||||||
|
o = DType( String( v.data() ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case H5T_ARRAY: {
|
||||||
|
const int ndims = H5Tget_array_ndims(atype_id);
|
||||||
|
CXZ_ASSERT(ndims, "array of dimension " << ndims << " not supported");
|
||||||
|
hsize_t dims;
|
||||||
|
H5Tget_array_dims(atype_id, &dims);
|
||||||
|
const hid_t att_id = H5Tget_super(atype_id);
|
||||||
|
const H5T_class_t atc = H5Tget_class(att_id);
|
||||||
|
switch(atc){
|
||||||
|
case H5T_INTEGER: {
|
||||||
|
Vector<Int> v(dims);
|
||||||
|
H5Aread(attr, atype_id, v.data());
|
||||||
|
o = DType(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case H5T_FLOAT: {
|
||||||
|
Vector<Double> v(dims);
|
||||||
|
H5Aread(attr, atype_id, v.data());
|
||||||
|
o = DType(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
CXZ_ERROR("attribute type id " << atype_id << " not supported");
|
||||||
|
}
|
||||||
|
H5Tclose(att_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
CXZ_ERROR("attribute type id " << atype_id << " not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
H5Tclose(atype_id);
|
||||||
|
H5Aclose(attr);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContentBase::attributeExists(const String& name) const
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(isOpen(), "tried to get attribute of closed object");
|
||||||
|
const htri_t ret = H5Aexists(mId, name.c_str());
|
||||||
|
CXZ_ASSERT(ret > 0, "error while reading attribute " << name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<String,DType> ContentBase::getAttributes() const
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(isOpen(), "tried to get attribute of closed object");
|
||||||
|
struct ItData
|
||||||
|
{
|
||||||
|
std::map<String,DType> d;
|
||||||
|
const ContentBase* _this;
|
||||||
|
} itdata;
|
||||||
|
itdata._this = this;
|
||||||
|
auto itop = [](hid_t loc_id, const char *attr_name,
|
||||||
|
const H5A_info_t* ainfo, void *op_data)
|
||||||
|
{
|
||||||
|
ItData* x = reinterpret_cast<ItData*>(op_data);
|
||||||
|
const String n = attr_name;
|
||||||
|
x->d[n] = x->_this->getAttribute( String(attr_name) );
|
||||||
|
return static_cast<herr_t>(0);
|
||||||
|
};
|
||||||
|
H5Aiterate(id(), H5_INDEX_NAME, H5_ITER_NATIVE, nullptr,
|
||||||
|
itop, &itdata);
|
||||||
|
return itdata.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<String,DType> ContentBase::getRecursiveAttributes() const
|
||||||
|
{
|
||||||
|
std::map<String,DType> out = getAttributes();
|
||||||
|
if(mParent){
|
||||||
|
std::map<String,DType> par = mParent->getRecursiveAttributes();
|
||||||
|
out.insert(par.begin(), par.end());
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
104
src/opt/hdf5/lib/h5_dataset.cc
Normal file
104
src/opt/hdf5/lib/h5_dataset.cc
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
|
||||||
|
#include "h5_dataset.h"
|
||||||
|
|
||||||
|
namespace CNORXZ
|
||||||
|
{
|
||||||
|
namespace hdf5
|
||||||
|
{
|
||||||
|
Dataset::Dataset(const String& name, const ContentBase* _parent) :
|
||||||
|
ContentBase(name, _parent)
|
||||||
|
{
|
||||||
|
if(exists()){
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dataset::~Dataset()
|
||||||
|
{
|
||||||
|
this->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentType Dataset::type() const
|
||||||
|
{
|
||||||
|
return ContentType::DSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Dataset::ro() const
|
||||||
|
{
|
||||||
|
return mParent->ro();
|
||||||
|
}
|
||||||
|
|
||||||
|
Dataset& Dataset::open()
|
||||||
|
{
|
||||||
|
if(mId == 0 and exists()){
|
||||||
|
mId = H5Dopen(mParent->id(), mName.c_str(), H5P_DEFAULT);
|
||||||
|
mType = H5Dget_type(mId);
|
||||||
|
|
||||||
|
mFilespace = H5Dget_space(mId);
|
||||||
|
SizeT ndims = H5Sget_simple_extent_ndims(mFilespace);
|
||||||
|
Vector<hsize_t> dims(ndims);
|
||||||
|
H5Sget_simple_extent_dims(mFilespace, dims.data(), nullptr);
|
||||||
|
|
||||||
|
Vector<RangePtr> rs(ndims);
|
||||||
|
for(SizeT i = 0; i != ndims; ++i){
|
||||||
|
rs[i] = CRangeFactory(dims[i]).create();
|
||||||
|
}
|
||||||
|
mDataRange = yrange(rs);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dataset& Dataset::close()
|
||||||
|
{
|
||||||
|
if(mId != 0){
|
||||||
|
H5Sclose(mFilespace);
|
||||||
|
H5Tclose(mType);
|
||||||
|
H5Dclose(mId);
|
||||||
|
mId = 0;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String Dataset::path() const
|
||||||
|
{
|
||||||
|
return mParent->path() + "/" + mName;
|
||||||
|
}
|
||||||
|
|
||||||
|
String Dataset::filename() const
|
||||||
|
{
|
||||||
|
return mParent->filename();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Dataset::exists() const
|
||||||
|
{
|
||||||
|
return H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dataset& Dataset::init(const RangePtr& dataRange, hid_t type)
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(not isOpen(), "tried to initialize dataset that is already extisting");
|
||||||
|
mDataRange = dataRange;
|
||||||
|
const H5T_class_t tc = H5Tget_class(type);
|
||||||
|
CXZ_ASSERT(tc != H5T_NO_CLASS, "id does not correspond to a data type"); // (did not found anythng better to check if type id is valid)...
|
||||||
|
const hid_t dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
|
||||||
|
// TODO: all sub-ranges explicity!!!:
|
||||||
|
const SizeT ndim = dataRange->dim();
|
||||||
|
Vector<hsize_t> exts(ndim);
|
||||||
|
for(SizeT i = 0; i != ndim; ++i){
|
||||||
|
exts[i] = static_cast<hsize_t>( dataRange->sub(i)->size() );
|
||||||
|
}
|
||||||
|
mFilespace = H5Screate_simple(ndim, exts.data(), NULL);
|
||||||
|
mType = type;
|
||||||
|
mId = H5Dcreate(mParent->id(), mName.c_str(), mType, mFilespace,
|
||||||
|
H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
|
||||||
|
H5Pclose(dcpl_id);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RangePtr& Dataset::dataRange() const
|
||||||
|
{
|
||||||
|
return mDataRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,9 +28,12 @@ namespace CNORXZ
|
||||||
|
|
||||||
File& File::open()
|
File& File::open()
|
||||||
{
|
{
|
||||||
|
if(isOpen()){
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
Int ex = this->exists();
|
Int ex = this->exists();
|
||||||
const String fn = this->filename();
|
const String fn = this->filename();
|
||||||
CXZ_ASSERT( ex != 2, "tried to open non-h5 file '" << fn << "'" );
|
CXZ_ASSERT( ishdf5(), "tried to open non-h5 file '" << fn << "'" );
|
||||||
if(mRo){
|
if(mRo){
|
||||||
CXZ_ASSERT( ex == 1, "could not open file as read-only: '"
|
CXZ_ASSERT( ex == 1, "could not open file as read-only: '"
|
||||||
<< fn << "' does not exist'");
|
<< fn << "' does not exist'");
|
||||||
|
@ -67,7 +70,7 @@ namespace CNORXZ
|
||||||
|
|
||||||
String File::path() const
|
String File::path() const
|
||||||
{
|
{
|
||||||
return String("/");
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
String File::filename() const
|
String File::filename() const
|
||||||
|
@ -75,21 +78,25 @@ namespace CNORXZ
|
||||||
return name();
|
return name();
|
||||||
}
|
}
|
||||||
|
|
||||||
Int File::exists() const
|
bool File::exists() const
|
||||||
{
|
{
|
||||||
Int ex = 0;
|
bool ex = false;
|
||||||
std::ifstream fs(this->filename().c_str(), std::ios_base::binary);
|
std::ifstream fs(this->filename().c_str(), std::ios_base::binary);
|
||||||
if(fs.good()){
|
if(fs.good()){
|
||||||
ex = 1; // file exists
|
ex = true; // file exists
|
||||||
}
|
}
|
||||||
fs.close();
|
fs.close();
|
||||||
if(ex != 0){
|
|
||||||
if(H5Fis_hdf5(this->filename().c_str()) <= 0){
|
|
||||||
ex = 2; // file not in h5 format
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool File::ishdf5() const
|
||||||
|
{
|
||||||
|
if(exists()){
|
||||||
|
if(H5Fis_hdf5(this->filename().c_str()) <= 0){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true; // a non-existing file can be created in hdf5 format
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
#include "h5_group.h"
|
#include "h5_group.h"
|
||||||
#include "h5_table.h"
|
#include "h5_table.h"
|
||||||
|
#include "h5_dataset.h"
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
@ -30,14 +31,16 @@ namespace CNORXZ
|
||||||
|
|
||||||
Group& Group::open()
|
Group& Group::open()
|
||||||
{
|
{
|
||||||
if(this->exists()){
|
if(not isOpen()){
|
||||||
mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT );
|
if(this->exists()){
|
||||||
|
mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mId = H5Gcreate( mParent->id(), mName.c_str(),
|
||||||
|
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
|
||||||
|
}
|
||||||
|
this->mkCont();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
mId = H5Gcreate( mParent->id(), mName.c_str(),
|
|
||||||
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
|
|
||||||
}
|
|
||||||
this->mkCont();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,14 +69,23 @@ namespace CNORXZ
|
||||||
return String();
|
return String();
|
||||||
}
|
}
|
||||||
|
|
||||||
Int Group::exists() const
|
bool Group::exists() const
|
||||||
{
|
{
|
||||||
return H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT) != 0 ? 1 : 0;
|
return H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ContentPtr& Group::get(const String& name) const
|
const ContentPtr& Group::get(const String& name) const
|
||||||
{
|
{
|
||||||
auto i = this->getIndexTo(name);
|
const String delim = "/";
|
||||||
|
const SizeT delimpos = name.find(delim);
|
||||||
|
const String thisname = name.substr(0, delimpos);
|
||||||
|
if(delimpos != String::npos and delimpos+1 < name.size()){
|
||||||
|
const String next = name.substr(delimpos+1);
|
||||||
|
auto g = getGroup(thisname);
|
||||||
|
g->open();
|
||||||
|
return g->get(next);
|
||||||
|
}
|
||||||
|
auto i = this->getIndexTo(thisname);
|
||||||
return *i;
|
return *i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +97,22 @@ namespace CNORXZ
|
||||||
return std::dynamic_pointer_cast<Group>( group );
|
return std::dynamic_pointer_cast<Group>( group );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sptr<Table> Group::getTable(const String& name) const
|
||||||
|
{
|
||||||
|
auto table = this->get(name);
|
||||||
|
CXZ_ASSERT(table->type() == ContentType::TABLE,
|
||||||
|
"element '" << name << "' is not of type TABLE");
|
||||||
|
return std::dynamic_pointer_cast<Table>( table );
|
||||||
|
}
|
||||||
|
|
||||||
|
Sptr<Dataset> Group::getDataset(const String& name) const
|
||||||
|
{
|
||||||
|
auto dset = this->get(name);
|
||||||
|
CXZ_ASSERT(dset->type() == ContentType::DSET,
|
||||||
|
"element '" << name << "' is not of type DSET");
|
||||||
|
return std::dynamic_pointer_cast<Dataset>( dset );
|
||||||
|
}
|
||||||
|
|
||||||
const MArray<ContentPtr>& Group::get() const
|
const MArray<ContentPtr>& Group::get() const
|
||||||
{
|
{
|
||||||
CXZ_ASSERT(this->isOpen(), "tried to get content of closed group");
|
CXZ_ASSERT(this->isOpen(), "tried to get content of closed group");
|
||||||
|
@ -118,10 +146,12 @@ namespace CNORXZ
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isTable(hid_t id)
|
static bool isTable(hid_t loc_id, const char* name)
|
||||||
{
|
{
|
||||||
|
const hid_t id = H5Dopen(loc_id, name, H5P_DEFAULT);
|
||||||
if(not H5Aexists(id, "CLASS")){
|
if(not H5Aexists(id, "CLASS")){
|
||||||
return false;
|
return false;
|
||||||
|
H5Dclose(id);
|
||||||
}
|
}
|
||||||
hid_t attrid = H5Aopen(id, "CLASS", H5P_DEFAULT);
|
hid_t attrid = H5Aopen(id, "CLASS", H5P_DEFAULT);
|
||||||
const hid_t atype = H5Aget_type(attrid);
|
const hid_t atype = H5Aget_type(attrid);
|
||||||
|
@ -130,6 +160,7 @@ namespace CNORXZ
|
||||||
const herr_t ret = H5Aread(attrid, atype, buff.data());
|
const herr_t ret = H5Aread(attrid, atype, buff.data());
|
||||||
H5Tclose(atype);
|
H5Tclose(atype);
|
||||||
H5Aclose(attrid);
|
H5Aclose(attrid);
|
||||||
|
H5Dclose(id);
|
||||||
if(ret != 0){
|
if(ret != 0){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -149,9 +180,9 @@ namespace CNORXZ
|
||||||
index();
|
index();
|
||||||
H5O_info_t oinfo;
|
H5O_info_t oinfo;
|
||||||
#if H5_VERS_MINOR > 10
|
#if H5_VERS_MINOR > 10
|
||||||
H5Oget_info(id, &oinfo, H5O_INFO_BASIC);
|
H5Oget_info_by_name(id, name, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT);
|
||||||
#else
|
#else
|
||||||
H5Oget_info(id, &oinfo);
|
H5Oget_info_by_name(id, name, &oinfo, H5P_DEFAULT);
|
||||||
#endif
|
#endif
|
||||||
switch (oinfo.type) {
|
switch (oinfo.type) {
|
||||||
case H5O_TYPE_GROUP: {
|
case H5O_TYPE_GROUP: {
|
||||||
|
@ -159,12 +190,11 @@ namespace CNORXZ
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case H5O_TYPE_DATASET: {
|
case H5O_TYPE_DATASET: {
|
||||||
if(isTable(id)){
|
if(isTable(id, name)){
|
||||||
*index = std::make_shared<Table>(sname, icd->parent);
|
*index = std::make_shared<Table>(sname, icd->parent);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CXZ_ERROR("IMPLEMENT!!!");
|
*index = std::make_shared<Dataset>(sname, icd->parent);
|
||||||
//*index = std::make_shared<DSet>(sname, icd->parent);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,20 @@ namespace CNORXZ
|
||||||
Table::Table(const String& name, const ContentBase* _parent) :
|
Table::Table(const String& name, const ContentBase* _parent) :
|
||||||
ContentBase(name, _parent)
|
ContentBase(name, _parent)
|
||||||
{
|
{
|
||||||
if(H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT)){
|
if(exists()){
|
||||||
hsize_t nfields = 0;
|
hsize_t nfields = 0;
|
||||||
hsize_t nrecords = 0;
|
hsize_t nrecords = 0;
|
||||||
H5TBget_table_info(mParent->id(), mName.c_str(), &nfields, &nrecords);
|
H5TBget_table_info(mParent->id(), mName.c_str(), &nfields, &nrecords);
|
||||||
mRecords = CRangeFactory( nrecords ).create();
|
mRecords = CRangeFactory( nrecords ).create();
|
||||||
|
Vector<Arr<char,256>> fieldnames(nfields);
|
||||||
Vector<char*> fieldsptr(nfields);
|
Vector<char*> fieldsptr(nfields);
|
||||||
|
for(SizeT i = 0; i != nfields; ++i){
|
||||||
|
fieldsptr[i] = fieldnames[i].data();
|
||||||
|
}
|
||||||
Vector<SizeT> offsets(nfields);
|
Vector<SizeT> offsets(nfields);
|
||||||
Vector<SizeT> sizes(nfields);
|
Vector<SizeT> sizes(nfields);
|
||||||
SizeT typesize = 0;
|
|
||||||
H5TBget_field_info(mParent->id(), mName.c_str(), fieldsptr.data(), sizes.data(),
|
H5TBget_field_info(mParent->id(), mName.c_str(), fieldsptr.data(), sizes.data(),
|
||||||
offsets.data(), &typesize);
|
offsets.data(), &mTypesize);
|
||||||
Vector<FieldID> fields(nfields);
|
Vector<FieldID> fields(nfields);
|
||||||
for(SizeT i = 0; i != nfields; ++i){
|
for(SizeT i = 0; i != nfields; ++i){
|
||||||
fields[i].first = i;
|
fields[i].first = i;
|
||||||
|
@ -62,6 +65,7 @@ namespace CNORXZ
|
||||||
if(mId == 0){
|
if(mId == 0){
|
||||||
mId = H5Dopen(mParent->id(), mName.c_str(), H5P_DEFAULT);
|
mId = H5Dopen(mParent->id(), mName.c_str(), H5P_DEFAULT);
|
||||||
mType = H5Dget_type(mId);
|
mType = H5Dget_type(mId);
|
||||||
|
mkTypes();
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -71,6 +75,7 @@ namespace CNORXZ
|
||||||
if(mId != 0){
|
if(mId != 0){
|
||||||
H5Tclose(mType);
|
H5Tclose(mType);
|
||||||
H5Dclose(mId);
|
H5Dclose(mId);
|
||||||
|
mId = 0;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +90,11 @@ namespace CNORXZ
|
||||||
return mParent->filename();
|
return mParent->filename();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Table::exists() const
|
||||||
|
{
|
||||||
|
return H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
Table& Table::initFieldNames(const Vector<String>& fnames)
|
Table& Table::initFieldNames(const Vector<String>& fnames)
|
||||||
{
|
{
|
||||||
CXZ_ASSERT(mFields == nullptr, "fields already initialized");
|
CXZ_ASSERT(mFields == nullptr, "fields already initialized");
|
||||||
|
@ -106,28 +116,61 @@ namespace CNORXZ
|
||||||
for(auto fi = fr->begin(); fi != fr->end(); ++fi){
|
for(auto fi = fr->begin(); fi != fr->end(); ++fi){
|
||||||
fields[fi.lex()] = (*fi).second.c_str();
|
fields[fi.lex()] = (*fi).second.c_str();
|
||||||
}
|
}
|
||||||
|
mTypesize = dsize;
|
||||||
const herr_t err = H5TBmake_table
|
const herr_t err = H5TBmake_table
|
||||||
(mName.c_str(), mParent->id(), mName.c_str(), mFields->size(), mRecords->size(), dsize,
|
(mName.c_str(), mParent->id(), mName.c_str(), mFields->size(), mRecords->size(), mTypesize,
|
||||||
fields.data(), mOffsets.data(), mTypes.data(), chunk_size, NULL, compress, data);
|
fields.data(), mOffsets.data(), mTypes.data(), chunk_size, NULL, compress, data);
|
||||||
CXZ_ASSERT(err >= 0, "error while initialzing table: error code = " << err);
|
CXZ_ASSERT(err >= 0, "error while initialzing table: error code = " << err);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Table& Table::appendRecord(SizeT n, const void* data, SizeT dsize)
|
Table& Table::appendRecords(SizeT n, const void* data)
|
||||||
{
|
{
|
||||||
mRecords = mRecords->extend( CRangeFactory(1).create() );
|
mRecords = mRecords->extend( CRangeFactory(n).create() );
|
||||||
const herr_t err = H5TBappend_records(mParent->id(), mName.c_str(), n, dsize,
|
const herr_t err = H5TBappend_records(mParent->id(), mName.c_str(), n, mTypesize,
|
||||||
mOffsets.data(), mSizes.data(), data);
|
mOffsets.data(), mSizes.data(), data);
|
||||||
CXZ_ASSERT(err >= 0, "error while appending record to table: error code = " << err);
|
CXZ_ASSERT(err >= 0, "error while appending record to table: error code = " << err);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Table& Table::readRecord(SizeT pos, SizeT n, char* data)
|
Table& Table::readRecords(SizeT pos, SizeT n, char* data)
|
||||||
{
|
{
|
||||||
CXZ_ERROR("not implemented!!!");
|
H5TBread_records(mParent->id(), mName.c_str(), pos, n, mTypesize, mOffsets.data(),
|
||||||
|
mSizes.data(), data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MArray<DType> Table::readRecord(SizeT pos) const
|
||||||
|
{
|
||||||
|
Vector<char> buf(mTypesize);
|
||||||
|
H5TBread_records(mParent->id(), mName.c_str(), pos, 1, mTypesize, mOffsets.data(),
|
||||||
|
mSizes.data(), buf.data());
|
||||||
|
MArray<DType> out(mFields);
|
||||||
|
auto fi = std::make_shared<CIndex>(mFields);
|
||||||
|
|
||||||
|
out(fi) = operation( [&](const SizeT& off, const std::function<DType(const char*)>& f){
|
||||||
|
return f( buf.data() + off );
|
||||||
|
}, mOffsets(fi), mInterpret(fi) );
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
MArray<DType> Table::read() const
|
||||||
|
{
|
||||||
|
Vector<char> buf(mTypesize*mRecords->size());
|
||||||
|
H5TBread_table(mParent->id(), mName.c_str(), mTypesize, mOffsets.data(),
|
||||||
|
mSizes.data(), buf.data());
|
||||||
|
MArray<DType> out(mRecords*mFields);
|
||||||
|
auto fi = std::make_shared<CIndex>(mFields);
|
||||||
|
auto ri = std::make_shared<CIndex>(mRecords);
|
||||||
|
|
||||||
|
out(ri*fi) = operation( [&](const SizeT& off, const std::function<DType(const char*)>& f, const SizeT r){
|
||||||
|
return f( buf.data() + r*mTypesize + off );
|
||||||
|
}, mOffsets(fi), mInterpret(fi), xpr(ri) );
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
const RangePtr& Table::fields() const
|
const RangePtr& Table::fields() const
|
||||||
{
|
{
|
||||||
return mFields;
|
return mFields;
|
||||||
|
@ -138,5 +181,64 @@ namespace CNORXZ
|
||||||
return mRecords;
|
return mRecords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Table::mkTypes()
|
||||||
|
{
|
||||||
|
mTypes = MArray<hid_t>(mFields);
|
||||||
|
auto i = std::make_shared<CIndex>(mFields);
|
||||||
|
mTypes(i) = operation( [&](const SizeT n){ return H5Tget_member_type( mType, n ); } , xpr(i) );
|
||||||
|
mInterpret = MArray<std::function<DType(const char*)>>(mFields);
|
||||||
|
mInterpret(i) = operation( [](const hid_t tid){
|
||||||
|
const hid_t tc = H5Tget_class(tid);
|
||||||
|
const size_t ts = H5Tget_size(tid);
|
||||||
|
const bool sig = H5Tget_sign(tid);
|
||||||
|
std::function<DType(const char*)> of;
|
||||||
|
switch(tc){
|
||||||
|
case H5T_INTEGER:{
|
||||||
|
switch(ts){
|
||||||
|
case 1:{ // 8-bit
|
||||||
|
of = sig ?
|
||||||
|
[](const char* d){ const int8_t x = *reinterpret_cast<const int8_t*>(d); return DType(static_cast<Int>(x)); } :
|
||||||
|
[](const char* d){ const uint8_t x = *reinterpret_cast<const uint8_t*>(d); return DType(static_cast<SizeT>(x)); };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:{ // 16-bit
|
||||||
|
of = sig ?
|
||||||
|
[](const char* d){ const int16_t x = *reinterpret_cast<const int16_t*>(d); return DType(static_cast<Int>(x)); } :
|
||||||
|
[](const char* d){ const uint16_t x = *reinterpret_cast<const uint16_t*>(d); return DType(static_cast<SizeT>(x)); };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:{ // 32-bit
|
||||||
|
of = sig ?
|
||||||
|
[](const char* d){ const int32_t x = *reinterpret_cast<const int32_t*>(d); return DType(static_cast<Int>(x)); } :
|
||||||
|
[](const char* d){ const uint32_t x = *reinterpret_cast<const uint32_t*>(d); return DType(static_cast<SizeT>(x)); };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8:{ // 64-bit
|
||||||
|
of = sig ?
|
||||||
|
[](const char* d){ const int64_t x = *reinterpret_cast<const int64_t*>(d); return DType(static_cast<LInt>(x)); } :
|
||||||
|
[](const char* d){ const uint64_t x = *reinterpret_cast<const uint64_t*>(d); return DType(static_cast<SizeT>(x)); };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
CXZ_ERROR("got integer of weird size: " << ts);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case H5T_FLOAT:{
|
||||||
|
if(ts == 4) {
|
||||||
|
of = [](const char* d){ const float x = *reinterpret_cast<const float*>(d); return DType(static_cast<Double>(x)); };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CXZ_ASSERT(ts == 8, "got float of weird size: " << ts);
|
||||||
|
of = [](const char* d){ const double x = *reinterpret_cast<const double*>(d); return DType(static_cast<Double>(x)); };
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
CXZ_ERROR("got unsupported type");
|
||||||
|
};
|
||||||
|
return of;
|
||||||
|
}, mTypes(i) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
|
||||||
|
add_definitions(-DTEST_NUMBER_FILE="${CMAKE_SOURCE_DIR}/src/tests/numbers.txt")
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/src/tests)
|
||||||
add_executable(h5basic h5_basic_unit_test.cc)
|
add_executable(h5basic h5_basic_unit_test.cc)
|
||||||
add_dependencies(h5basic cnorxz cnorxzhdf5)
|
add_dependencies(h5basic cnorxz cnorxzhdf5 test_lib)
|
||||||
target_link_libraries(h5basic ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${HDF5_LIBS} cnorxz cnorxzhdf5)
|
target_link_libraries(h5basic ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${HDF5_LIBS} cnorxz cnorxzhdf5 test_lib)
|
||||||
add_test(NAME h5basic COMMAND h5basic)
|
add_test(NAME h5basic COMMAND h5basic)
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "cnorxz_hdf5.h"
|
#include "cnorxz_hdf5.h"
|
||||||
|
#include "test_numbers.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
using namespace CNORXZ;
|
using namespace CNORXZ;
|
||||||
using namespace CNORXZ::hdf5;
|
using namespace CNORXZ::hdf5;
|
||||||
|
using Test::Numbers;
|
||||||
|
|
||||||
static const String testh5file = "test_file.h5";
|
static const String testh5file = "test_file.h5";
|
||||||
|
|
||||||
|
@ -39,24 +41,43 @@ namespace
|
||||||
Group_Test()
|
Group_Test()
|
||||||
{
|
{
|
||||||
mFileName = testh5file;
|
mFileName = testh5file;
|
||||||
mGrps = { "gr1", "gr2" };
|
|
||||||
mFs = {"field1","second","real"};
|
mFs = {"field1","second","real"};
|
||||||
Vector<Tuple<SizeT,Int,Double>> v
|
// Tuple has reverse (!) memory ordering:
|
||||||
( { {0, -6, 3.141},
|
Vector<Tuple<Double,Int,SizeT>> v
|
||||||
{3, -8, 0.789},
|
( { { 3.141, -6, 0 },
|
||||||
{34, 4, 10.009},
|
{ 0.789, -8, 3 },
|
||||||
{2, -777, -9.77},
|
{ 10.009, 4, 34 },
|
||||||
{321, 0, -0.003}
|
{ -9.77, -777, 2 },
|
||||||
|
{ -0.003, 0, 321 }
|
||||||
} );
|
} );
|
||||||
RangePtr rs = CRangeFactory(v.size()).create();
|
RangePtr rs = CRangeFactory(v.size()).create();
|
||||||
mTabA = MArray<Tuple<SizeT,Int,Double>>(rs, std::move(v));
|
RangePtr fs = CRangeFactory(mFs.size()).create();
|
||||||
|
mTabA = MArray<Tuple<Double,Int,SizeT>>(rs, std::move(v));
|
||||||
|
mTabD = MArray<DType>(rs*fs);
|
||||||
|
CIndex i(rs);
|
||||||
|
CIndex j(fs);
|
||||||
|
for(i = 0; i.lex() != rs->size(); ++i){
|
||||||
|
iter<0,3>( [&](auto jj)
|
||||||
|
{ j = jj; mTabD[i*j] = DType(std::get<3-jj-1>(v[i.lex()])); }, NoF{} );
|
||||||
|
}
|
||||||
|
|
||||||
|
const SizeT ddim = 5;
|
||||||
|
Vector<RangePtr> dranges(ddim);
|
||||||
|
dranges[0] = CRangeFactory(7).create();
|
||||||
|
dranges[1] = CRangeFactory(3).create();
|
||||||
|
dranges[2] = CRangeFactory(13).create();
|
||||||
|
dranges[3] = CRangeFactory(5).create();
|
||||||
|
dranges[4] = CRangeFactory(2).create();
|
||||||
|
const RangePtr drange = yrange(dranges);
|
||||||
|
mData = MArray<Double>( drange, Numbers::get(0,drange->size()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
String mFileName;
|
String mFileName;
|
||||||
Vector<String> mGrps;
|
|
||||||
|
|
||||||
Vector<String> mFs;
|
Arr<String,3> mFs;
|
||||||
MArray<Tuple<SizeT,Int,Double>> mTabA;
|
MArray<Tuple<Double,Int,SizeT>> mTabA;
|
||||||
|
MArray<DType> mTabD;
|
||||||
|
MArray<Double> mData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,9 +101,28 @@ namespace
|
||||||
File h5f(mFileName, false);
|
File h5f(mFileName, false);
|
||||||
EXPECT_FALSE(h5f.ro());
|
EXPECT_FALSE(h5f.ro());
|
||||||
h5f.open();
|
h5f.open();
|
||||||
|
h5f.addAttribute("fprop", static_cast<Double>(3.141));
|
||||||
h5f.addGroup("gr1");
|
h5f.addGroup("gr1");
|
||||||
|
h5f.getGroup("gr1")->addAttribute("att1", String("text"));
|
||||||
h5f.addGroup("gr2");
|
h5f.addGroup("gr2");
|
||||||
EXPECT_EQ(h5f.get().size(), 2u);
|
h5f.addGroup("foo");
|
||||||
|
h5f.addGroup("bar");
|
||||||
|
h5f.addGroup("moregroups");
|
||||||
|
auto moregroups = h5f.getGroup("moregroups");
|
||||||
|
moregroups->open().addGroup("evenmore");
|
||||||
|
auto evenmore = moregroups->getGroup("evenmore");
|
||||||
|
evenmore->open();
|
||||||
|
evenmore->addAttribute("moreatt", static_cast<Int>(12));
|
||||||
|
evenmore->addGroup("we");
|
||||||
|
evenmore->getGroup("we")->addAttribute("wex", static_cast<Int>(9));
|
||||||
|
evenmore->getGroup("we")->addAttribute("xy", String("xys"));
|
||||||
|
evenmore->addGroup("need");
|
||||||
|
evenmore->getGroup("need")->addAttribute("wex", static_cast<Int>(7));
|
||||||
|
evenmore->addGroup("more");
|
||||||
|
evenmore->getGroup("more")->addAttribute("wex", static_cast<Int>(4));
|
||||||
|
evenmore->addGroup("groups");
|
||||||
|
evenmore->getGroup("groups")->addAttribute("wex", static_cast<Int>(2));
|
||||||
|
EXPECT_EQ(h5f.get().size(), 5u);
|
||||||
h5f.close();
|
h5f.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +131,15 @@ namespace
|
||||||
File h5f(mFileName, false);
|
File h5f(mFileName, false);
|
||||||
h5f.open();
|
h5f.open();
|
||||||
h5f.getGroup("gr1")->open().addTable("tab1", mTabA, mFs);
|
h5f.getGroup("gr1")->open().addTable("tab1", mTabA, mFs);
|
||||||
h5f.getGroup("gr2")->open().addTable("tab1", mTabA, mFs);
|
h5f.getGroup("moregroups")->open().getGroup("evenmore")->open().getGroup("need")->open().addTable("tab1", mTabA, mFs);
|
||||||
|
h5f.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Group_Test, CreateDataset)
|
||||||
|
{
|
||||||
|
File h5f(mFileName, false);
|
||||||
|
h5f.open();
|
||||||
|
h5f.getGroup("gr2")->open().addDataset("dat1", mData);
|
||||||
h5f.close();
|
h5f.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +148,146 @@ namespace
|
||||||
File h5f(mFileName, true);
|
File h5f(mFileName, true);
|
||||||
h5f.open();
|
h5f.open();
|
||||||
EXPECT_TRUE(h5f.ro());
|
EXPECT_TRUE(h5f.ro());
|
||||||
EXPECT_EQ(h5f.get().size(), 2u);
|
EXPECT_EQ(h5f.get().size(), 5u);
|
||||||
|
|
||||||
|
EXPECT_THROW(h5f.getGroup("gr0"), std::runtime_error);
|
||||||
|
auto gr1 = h5f.getGroup("gr1");
|
||||||
|
gr1->open();
|
||||||
|
auto tab = gr1->getTable("tab1");
|
||||||
|
DType att = gr1->getAttribute("att1");
|
||||||
|
EXPECT_EQ(att.str(), "text");
|
||||||
|
VCHECK(tab->path());
|
||||||
|
EXPECT_EQ(tab->fields()->size(), 3u);
|
||||||
|
EXPECT_EQ(tab->records()->size(), 5u);
|
||||||
|
|
||||||
|
EXPECT_THROW(h5f.getTable("moregroups/evenmore/need/tab1/a"), std::runtime_error);
|
||||||
|
auto tab2 = h5f.getTable("moregroups/evenmore/need/tab1/");
|
||||||
|
EXPECT_EQ(tab2->fields()->size(), 3u);
|
||||||
|
EXPECT_EQ(tab2->records()->size(), 5u);
|
||||||
|
|
||||||
|
h5f.iter( [](const auto& c) { VCHECK(c->path()); } )();
|
||||||
|
h5f.iterRecursive( [](const auto& c) { VCHECK(c->path()); } )();
|
||||||
|
h5f.iterRecursive( [](const auto& c) { c->open(); VCHECK(toString(c->getRecursiveAttributes())); } )();
|
||||||
|
h5f.iterRecursive( [](const auto& c) {
|
||||||
|
if(c->type() == ContentType::TABLE) { c->open(); VCHECK(toString(c->getRecursiveAttributes())); }
|
||||||
|
} )();
|
||||||
|
h5f.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Group_Test, ReadTable)
|
||||||
|
{
|
||||||
|
typedef Tuple<Double,Int,SizeT> RecType;
|
||||||
|
|
||||||
|
File h5f(mFileName, true);
|
||||||
|
h5f.open();
|
||||||
|
auto tab = h5f.getGroup("gr1")->open().getTable("tab1", RecType());
|
||||||
|
EXPECT_EQ(tab->fields()->size(), 3u);
|
||||||
|
EXPECT_EQ(tab->records()->size(), 5u);
|
||||||
|
tab->open();
|
||||||
|
auto cont = tab->read();
|
||||||
|
EXPECT_EQ(cont.size(), mTabA.size());
|
||||||
|
CIndex i(mTabA.range());
|
||||||
|
for(; i.lex() != i.lmax().val(); ++i){
|
||||||
|
EXPECT_EQ( cont[i], mTabA[i] );
|
||||||
|
}
|
||||||
|
auto dtab = h5f.getGroup("gr1")->open().getTable("tab1");
|
||||||
|
auto dcont = dtab->read();
|
||||||
|
EXPECT_EQ(dcont.range()->dim(), 2u);
|
||||||
|
EXPECT_EQ(dcont.range()->sub(0)->size(), 5u);
|
||||||
|
EXPECT_EQ(dcont.range()->sub(1)->size(), 3u);
|
||||||
|
for(auto ai = dcont.begin(); ai != dcont.end(); ++ai){
|
||||||
|
EXPECT_EQ(dcont[ai].str(), mTabD[ai].str());
|
||||||
|
}
|
||||||
|
h5f.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Group_Test, ReadDataset)
|
||||||
|
{
|
||||||
|
File h5f(mFileName, true);
|
||||||
|
h5f.open();
|
||||||
|
auto dset = h5f.getGroup("gr2")->open().getDataset("dat1", Double{});
|
||||||
|
auto data = dset->read();
|
||||||
|
EXPECT_EQ(data.range()->dim(), 5u);
|
||||||
|
for(SizeT i = 0; i != 5u; ++i){
|
||||||
|
EXPECT_EQ( data.range()->sub(i)->size(), mData.range()->sub(i)->size() );
|
||||||
|
}
|
||||||
|
auto i = std::make_shared<CIndex>(data.range());
|
||||||
|
i->ifor( operation( [](Double a, Double b) { EXPECT_EQ(a,b); }, data(i), mData(i) ), NoF{} )();
|
||||||
|
h5f.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Group_Test, ReadDatasetPart)
|
||||||
|
{
|
||||||
|
File h5f(mFileName, true);
|
||||||
|
h5f.open();
|
||||||
|
auto dset = h5f.getGroup("gr2")->open().getDataset("dat1", Double{});
|
||||||
|
YIndex beg(dset->dataRange());
|
||||||
|
beg.setSub(0,2);
|
||||||
|
YIndex end = beg - 1;
|
||||||
|
end.setSub(0,2);
|
||||||
|
auto data = dset->read(beg,end);
|
||||||
|
EXPECT_EQ( data.range()->dim(), 5u );
|
||||||
|
EXPECT_EQ( data.range()->sub(0)->size(), 1u );
|
||||||
|
for(SizeT i = 1; i != 5u; ++i){
|
||||||
|
EXPECT_EQ( data.range()->sub(i)->size(), mData.range()->sub(i)->size() );
|
||||||
|
}
|
||||||
|
auto i = std::make_shared<CIndex>(data.range());
|
||||||
|
auto j = std::make_shared<DIndex>( beg.pack().get(0) );
|
||||||
|
i->ifor( operation( [](Double a, Double b) { EXPECT_EQ(a,b); }, data(i), mData(j*i) ), NoF{} )();
|
||||||
|
h5f.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Group_Test, Read2)
|
||||||
|
{
|
||||||
|
File h5f(mFileName, true);
|
||||||
|
h5f.open();
|
||||||
|
Vector<String> paths;
|
||||||
|
Vector<String> attrs;
|
||||||
|
|
||||||
|
auto checkatt = [](const std::map<String,DType>& m,
|
||||||
|
const std::map<String,DType>& cs) {
|
||||||
|
for(const auto& c: cs){
|
||||||
|
if(m.count(c.first)){
|
||||||
|
if(m.at(c.first).str() != c.second.str()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
std::map<String,DType> constr;
|
||||||
|
constr["wex"] = DType(Vector<Int>{7});
|
||||||
|
constr["second"] = DType(static_cast<Int>(-777));
|
||||||
|
h5f.iterRecursive( [&](const auto& c) {
|
||||||
|
if(c->type() == ContentType::TABLE) {
|
||||||
|
c->open();
|
||||||
|
auto av = c->getRecursiveAttributes();
|
||||||
|
auto cx = std::dynamic_pointer_cast<Table>(c);
|
||||||
|
SizeT cnt = 0;
|
||||||
|
cx->iterRecords( [&](const MArray<DType>& r) {
|
||||||
|
auto ax = av;
|
||||||
|
auto fi = UIndex<std::pair<SizeT,String>>(r.range()->sub(0));
|
||||||
|
for(; fi.lex() != fi.lmax().val(); ++fi) { ax[fi.meta().second] = r[fi]; }
|
||||||
|
attrs.push_back(toString(ax));
|
||||||
|
if(checkatt(ax,constr)){
|
||||||
|
paths.push_back(c->path()+"/@"+toString(cnt));
|
||||||
|
}
|
||||||
|
++cnt;
|
||||||
|
} )();
|
||||||
|
}
|
||||||
|
} )();
|
||||||
|
for(const auto& x: attrs){
|
||||||
|
VCHECK(x);
|
||||||
|
}
|
||||||
|
for(const auto& p: paths){
|
||||||
|
VCHECK(p);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(paths.size(), 1u);
|
||||||
|
EXPECT_EQ(paths[0], "/moregroups/evenmore/need/tab1/@3");
|
||||||
|
h5f.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ namespace
|
||||||
{
|
{
|
||||||
GMIndex<MFormat<4>,CIndex,CIndex,CIndex,CIndex> mi(mRange);
|
GMIndex<MFormat<4>,CIndex,CIndex,CIndex,CIndex> mi(mRange);
|
||||||
MIndex<CIndex,CIndex,CIndex,CIndex,CIndex> mi2(mRange2);
|
MIndex<CIndex,CIndex,CIndex,CIndex,CIndex> mi2(mRange2);
|
||||||
|
GMIndex<MFormat<4>,CIndex,GMIndex<MFormat<3>,CIndex,CIndex,CIndex>,CIndex,CIndex> mi32(mRange);
|
||||||
EXPECT_EQ(mi.lmax().val(), mRange->size());
|
EXPECT_EQ(mi.lmax().val(), mRange->size());
|
||||||
EXPECT_EQ(mi2.lmax().val(), mRange2->size());
|
EXPECT_EQ(mi2.lmax().val(), mRange2->size());
|
||||||
auto yi = indexAs<YIndex>( mRange->begin() );
|
auto yi = indexAs<YIndex>( mRange->begin() );
|
||||||
|
@ -79,9 +80,20 @@ namespace
|
||||||
|
|
||||||
yi.setFormat( YFormat( Vector<SizeT>{ mi2.format()[CSizeT<0>{}].val(), mi2.format()[CSizeT<1>{}].val(), mi2.format()[CSizeT<2>{}].val(), mi2.format()[CSizeT<4>{}].val() } ) );
|
yi.setFormat( YFormat( Vector<SizeT>{ mi2.format()[CSizeT<0>{}].val(), mi2.format()[CSizeT<1>{}].val(), mi2.format()[CSizeT<2>{}].val(), mi2.format()[CSizeT<4>{}].val() } ) );
|
||||||
VCHECK(toString(yi.deepFormat()));
|
VCHECK(toString(yi.deepFormat()));
|
||||||
|
|
||||||
mi.reformat( yi.deepFormat(), yi.deepMax() );
|
mi.reformat( yi.deepFormat(), yi.deepMax() );
|
||||||
VCHECK(toString(mi.deepFormat()));
|
VCHECK(toString(mi.deepFormat()));
|
||||||
VCHECK(toString(mi.deepMax()));
|
VCHECK(toString(mi.deepMax()));
|
||||||
|
|
||||||
|
yi.setFormat( YFormat( Vector<SizeT>{ 13, 143, 1, 15015 } ) );
|
||||||
|
VCHECK(toString(yi.deepFormat()));
|
||||||
|
mi.reformat( yi.deepFormat(), yi.deepMax() );
|
||||||
|
VCHECK(toString(mi.deepFormat()));
|
||||||
|
VCHECK(toString(mi.deepMax()));
|
||||||
|
|
||||||
|
mi32.reformat( Vector<SizeT> { 105,1,2310,1155 }, Vector<SizeT> { 11,105,13,2 } );
|
||||||
|
VCHECK(toString(yi.deepFormat()));
|
||||||
|
mi32.reformat( yi.deepFormat(), yi.deepMax() );
|
||||||
|
VCHECK(toString(mi32.deepFormat()));
|
||||||
|
VCHECK(toString(mi32.deepMax()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue