dev #2
51 changed files with 3069 additions and 510 deletions
|
@ -7,7 +7,7 @@ steps:
|
|||
- source /opt/rh/gcc-toolset-9/enable
|
||||
- mkdir build-gcc
|
||||
- cd build-gcc
|
||||
- cmake3 -DRUN_PIPELINE=on -DSCALAR_BUILD=on ..
|
||||
- cmake3 -DSCALAR_BUILD=on ..
|
||||
- make -j2
|
||||
- make test
|
||||
- cd ..
|
||||
|
|
|
@ -2,27 +2,44 @@ cmake_minimum_required(VERSION 3.0)
|
|||
|
||||
project(cnorxz)
|
||||
|
||||
# LIB VERSION
|
||||
|
||||
set(VERSION_PART "pre")
|
||||
set(VERSION_TAG_HASH "6857e3fc7d0af25db3a925791d1cabc6342b930a")
|
||||
|
||||
# OPTIONS
|
||||
|
||||
option(SCALAR_BUILD "" OFF)
|
||||
|
||||
# INCLUDES
|
||||
|
||||
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 tag -l --sort=refname 'v*' | tail -n1" OUTPUT_VARIABLE GIT_TAG 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)
|
||||
execute_process(COMMAND bash "-c" "git rev-parse --abbrev-ref HEAD" OUTPUT_VARIABLE GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# BUILD / CHECK VERSION STRING
|
||||
|
||||
message(STATUS "${GIT_HASH}")
|
||||
option(RUN_PIPELINE "" OFF)
|
||||
option(SCALAR_BUILD "" OFF)
|
||||
if(RUN_PIPELINE)
|
||||
set(VERSION "v0.0.0-test")
|
||||
else()
|
||||
message(STATUS "${GIT_TAG}")
|
||||
message(STATUS "${GIT_TAG_HASH}")
|
||||
string(SUBSTRING "${GIT_TAG}" 1 -1 VERSION)
|
||||
if(NOT ("${GIT_HASH}" EQUAL "${GIT_TAG_HASH}"))
|
||||
message(STATUS "${VERSION_PART}")
|
||||
message(STATUS "${VERSION_TAG_HASH}")
|
||||
set(VERSION "${VERSION_PART}")
|
||||
if(NOT ("${GIT_BRANCH}" EQUAL "release"))
|
||||
if(NOT ("${GIT_HASH}" EQUAL "${VERSION_TAG_HASH}"))
|
||||
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()
|
||||
message(STATUS "version = ${VERSION}")
|
||||
|
||||
# CHECK COMPILER
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 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")
|
||||
endif()
|
||||
|
||||
# FLAGS
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++17 -Wpedantic -O2 -march=native -faligned-new -funroll-loops -fopenmp")
|
||||
|
||||
# TESTING
|
||||
|
||||
enable_testing()
|
||||
|
||||
# INSTALL PATH
|
||||
|
||||
if(IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}")
|
||||
set(INSTALL_PATH ${CMAKE_INSTALL_PREFIX})
|
||||
else()
|
||||
|
@ -43,6 +66,8 @@ else()
|
|||
endif()
|
||||
message(STATUS "found absolute install path '${INSTALL_PATH}'")
|
||||
|
||||
# SCALAR / INTRINSICS
|
||||
|
||||
if(NOT ${SCALAR_BUILD})
|
||||
message(STATUS "check for intrinsics")
|
||||
check_avx()
|
||||
|
@ -55,6 +80,8 @@ if(NOT ${SCALAR_BUILD})
|
|||
endif()
|
||||
endif()
|
||||
|
||||
# CHECK LIBRARIES : GTest
|
||||
|
||||
message(STATUS "check for libraries")
|
||||
find_package( GTest REQUIRED )
|
||||
if(GTest_FOUND)
|
||||
|
@ -63,6 +90,8 @@ else()
|
|||
message(FATAL_ERROR "GTest not found")
|
||||
endif()
|
||||
|
||||
# CHECK LIBRARIES : Threads
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
if(Threads_FOUND)
|
||||
#include_directories(${Threads_INCLUDE_DIRS})
|
||||
|
@ -70,12 +99,16 @@ else()
|
|||
message(FATAL_ERROR "Threads not found")
|
||||
endif()
|
||||
|
||||
# CHECK LIBRARIES : hdf5
|
||||
|
||||
if(DEFINED ENABLE_hdf5)
|
||||
set(ENABLE_hdf5 ${ENABLE_hdf5} CACHE BOOL "enable hdf5")
|
||||
else()
|
||||
set(ENABLE_hdf5 TRUE CACHE BOOL "enable hdf5")
|
||||
endif()
|
||||
|
||||
# CHECK LIBRARIES : cereal
|
||||
|
||||
if(DEFINED ENABLE_cereal)
|
||||
set(ENABLE_cereal ${ENABLE_cereal} CACHE BOOL "enable hdf5")
|
||||
else()
|
||||
|
@ -96,8 +129,12 @@ else()
|
|||
endif()
|
||||
endif()
|
||||
|
||||
# DEFINES
|
||||
|
||||
add_definitions(-DVERSION="${VERSION}")
|
||||
add_definitions(-DGIT_COMMIT="${GIT_HASH}")
|
||||
add_definitions(-DCXX_FLAGS="${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# CONTINUE WITH SUB-DIRECTORIES
|
||||
|
||||
add_subdirectory(src)
|
||||
|
|
|
@ -36,9 +36,9 @@ The tools of the library are accessible within the namespace `CNORXZ`.
|
|||
|
||||
### 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:
|
||||
|
||||
|
@ -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.
|
||||
|
||||
#### 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>`).
|
||||
|
||||
|
@ -66,7 +66,7 @@ Apart from range specific indices, there exist also special indices:
|
|||
|
||||
* `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`.
|
||||
|
||||
|
|
|
@ -33,11 +33,16 @@ namespace CNORXZ
|
|||
{
|
||||
std::stringstream ss;
|
||||
ss << "[";
|
||||
auto it = a.begin();
|
||||
for(; it != a.end()-1; ++it){
|
||||
ss << toString(*it) << ",";
|
||||
if(a.size() == 0){
|
||||
ss << "]";
|
||||
}
|
||||
else {
|
||||
auto it = a.begin();
|
||||
for(; it != a.end()-1; ++it){
|
||||
ss << toString(*it) << ",";
|
||||
}
|
||||
ss << toString(*it) << "]";
|
||||
}
|
||||
ss << toString(*it) << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
@ -46,11 +51,16 @@ namespace CNORXZ
|
|||
{
|
||||
std::stringstream ss;
|
||||
ss << "(";
|
||||
auto it = a.begin();
|
||||
for(; it != a.end()-1; ++it){
|
||||
ss << toString(*it) << ",";
|
||||
if constexpr(N == 0){
|
||||
ss << ")";
|
||||
}
|
||||
else {
|
||||
auto it = a.begin();
|
||||
for(; it != a.end()-1; ++it){
|
||||
ss << toString(*it) << ",";
|
||||
}
|
||||
ss << toString(*it) << ")";
|
||||
}
|
||||
ss << toString(*it) << ")";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
@ -73,6 +83,26 @@ namespace CNORXZ
|
|||
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>
|
||||
String toString(const T& a)
|
||||
{
|
||||
|
|
|
@ -97,6 +97,20 @@ namespace CNORXZ
|
|||
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
|
||||
*/
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
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
|
||||
|
||||
**/
|
||||
|
@ -28,9 +28,9 @@
|
|||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/**********************
|
||||
* standard types *
|
||||
**********************/
|
||||
/*====================+
|
||||
| standard types |
|
||||
=====================*/
|
||||
|
||||
typedef std::intptr_t PtrId;
|
||||
typedef int32_t Int;
|
||||
|
@ -80,9 +80,9 @@ namespace CNORXZ
|
|||
template <SizeT N>
|
||||
using CSizeT = std::integral_constant<SizeT,N>;
|
||||
|
||||
/*********************
|
||||
* library types *
|
||||
*********************/
|
||||
/*===================+
|
||||
| library types |
|
||||
+===================*/
|
||||
|
||||
/***
|
||||
Naming Prefixes:
|
||||
|
@ -302,9 +302,9 @@ namespace CNORXZ
|
|||
template <class CXpr>
|
||||
class Contraction;
|
||||
|
||||
/*********************
|
||||
* derived types *
|
||||
*********************/
|
||||
/*===================+
|
||||
| derived types |
|
||||
+===================*/
|
||||
|
||||
template <typename T>
|
||||
using Vector = std::vector<T,Allocator<T>>;
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
namespace CNORXZ
|
||||
{
|
||||
|
||||
/**********************
|
||||
* COpInterface *
|
||||
**********************/
|
||||
/*====================+
|
||||
| COpInterface |
|
||||
+====================*/
|
||||
|
||||
template <class OpT>
|
||||
template <class F, class IndexT>
|
||||
|
@ -37,9 +37,9 @@ namespace CNORXZ
|
|||
}
|
||||
|
||||
|
||||
/*********************
|
||||
* OpInterface *
|
||||
*********************/
|
||||
/*===================+
|
||||
| OpInterface |
|
||||
+===================*/
|
||||
|
||||
template <class OpT>
|
||||
template <class IndexT, class F, class... Args>
|
||||
|
@ -56,9 +56,9 @@ namespace CNORXZ
|
|||
}
|
||||
|
||||
|
||||
/***************
|
||||
* COpRoot *
|
||||
***************/
|
||||
/*=============+
|
||||
| COpRoot |
|
||||
+=============*/
|
||||
|
||||
template <typename T, class IndexT>
|
||||
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);
|
||||
}
|
||||
|
||||
/****************
|
||||
* 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>
|
||||
constexpr OpCont<T,IndexT>::OpCont(const Sptr<IndexT>& ind) :
|
||||
|
@ -236,9 +279,9 @@ namespace CNORXZ
|
|||
return mC.data();
|
||||
}
|
||||
|
||||
/****************
|
||||
* OpRoot *
|
||||
****************/
|
||||
/*==============+
|
||||
| OpRoot |
|
||||
+==============*/
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr OpRoot<T,IndexT>::OpRoot(ArrayBase<T>& a, const Sptr<IndexT>& ind) :
|
||||
|
@ -327,9 +370,9 @@ namespace CNORXZ
|
|||
return OpRoot<T,IndexT>(a, ind);
|
||||
}
|
||||
|
||||
/*******************
|
||||
* Operation *
|
||||
*******************/
|
||||
/*=================+
|
||||
| Operation |
|
||||
+=================*/
|
||||
|
||||
template <class F, class... Ops>
|
||||
constexpr Operation<F,Ops...>::Operation(F&& f, const Ops&... ops) :
|
||||
|
@ -411,9 +454,9 @@ namespace CNORXZ
|
|||
}
|
||||
}
|
||||
|
||||
/*********************
|
||||
* Contraction *
|
||||
*********************/
|
||||
/*===================+
|
||||
| Contraction |
|
||||
+===================*/
|
||||
|
||||
template <class CXpr>
|
||||
constexpr Contraction<CXpr>::Contraction(CXpr&& cxpr) :
|
||||
|
@ -447,9 +490,9 @@ namespace CNORXZ
|
|||
return Contraction<CXprT>( i->ifor( op, f ) );
|
||||
}
|
||||
|
||||
/************************
|
||||
* various functions *
|
||||
************************/
|
||||
/*======================+
|
||||
| various functions |
|
||||
+======================*/
|
||||
|
||||
template <class IndexT>
|
||||
constexpr decltype(auto) indexOp(const Sptr<IndexT>& i)
|
||||
|
|
|
@ -97,6 +97,36 @@ namespace CNORXZ
|
|||
template <typename T, class IndexT>
|
||||
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>
|
||||
class OpCont : public OpInterface<OpCont<T,IndexT>>
|
||||
{
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
/**
|
||||
|
||||
@file include/ranges/crange.h
|
||||
@brief ...
|
||||
@brief CRange and CIndex declaration.
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
@ -35,8 +34,8 @@ namespace CNORXZ
|
|||
DEFAULT_MEMBERS(CIndex); /**< default constructors and assignments */
|
||||
|
||||
/** Construct index from range and position.
|
||||
@param range Range to iterate over
|
||||
@param pos lexicographic position
|
||||
@param range Range to iterate over.
|
||||
@param pos lexicographic position.
|
||||
*/
|
||||
CIndex(const RangePtr& range, SizeT pos = 0);
|
||||
|
||||
|
@ -80,7 +79,7 @@ namespace CNORXZ
|
|||
SizeT operator*() const;
|
||||
|
||||
/** @copydoc IndexInterface::dim() */
|
||||
SizeT dim() const; // = 1
|
||||
SizeT dim() const;
|
||||
|
||||
/** @copydoc IndexInterface::range() */
|
||||
Sptr<RangeType> range() const;
|
||||
|
@ -124,30 +123,29 @@ namespace CNORXZ
|
|||
Sptr<RangeType> mRangePtr;
|
||||
};
|
||||
|
||||
/** make index pack of a CIndex and another index
|
||||
@tparam type of the second index
|
||||
@param a pointer to CIndex
|
||||
@param b pointer to another index
|
||||
/** Make index pack of a CIndex and another index.
|
||||
@param a pointer to CIndex.
|
||||
@param b pointer to another index.
|
||||
*/
|
||||
template <class I>
|
||||
decltype(auto) operator*(const Sptr<CIndex>& a, const Sptr<I>& b);
|
||||
|
||||
/** ****
|
||||
specific factory for CRange
|
||||
Specific factory for CRange.
|
||||
*/
|
||||
class CRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
public:
|
||||
typedef CRange oType;
|
||||
|
||||
/** construct and setup factory
|
||||
@param size size of the range to be constructed
|
||||
/** Construct and setup factory.
|
||||
@param size Size of the range to be constructed.
|
||||
*/
|
||||
CRangeFactory(SizeT size);
|
||||
|
||||
/** construct and setup factory
|
||||
@param size size of the range to be constructed
|
||||
@param ref range the range to be constructed is related to
|
||||
/** Construct and setup factory.
|
||||
@param size Size of the range to be constructed.
|
||||
@param ref Range the range to be constructed is related to.
|
||||
*/
|
||||
CRangeFactory(SizeT size, RangePtr ref);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@brief ...
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
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>
|
||||
I indexAs(const DIndex& i)
|
||||
{
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
/**
|
||||
|
||||
@file include/ranges/dindex.h
|
||||
@brief ...
|
||||
@brief DIndex declaration
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
@ -154,6 +153,13 @@ namespace CNORXZ
|
|||
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:
|
||||
DIndex can have sub-indices
|
||||
*/
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@brief ...
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
@ -20,7 +20,17 @@
|
|||
|
||||
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>
|
||||
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>::RangeType RangeType;
|
||||
|
||||
DEFAULT_MEMBERS(EIndex);
|
||||
DEFAULT_MEMBERS(EIndex); /**< default constructors and assignments */
|
||||
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>
|
||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||
|
||||
|
@ -38,6 +54,10 @@ namespace CNORXZ
|
|||
Sptr<LIndex<SIndex<MetaT,S>,L>> mLI;
|
||||
};
|
||||
|
||||
/** ***
|
||||
EIndex is an index
|
||||
@see is_index
|
||||
*/
|
||||
template <typename MetaT, SizeT S, SizeT L>
|
||||
struct is_index<EIndex<MetaT,S,L>>
|
||||
{
|
||||
|
@ -54,24 +74,51 @@ namespace CNORXZ
|
|||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
decltype(auto) eplex(const Sptr<Index>& i, CSizeT<S> s, CSizeT<L1> l1, CSizeT<L2> l2);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@brief ...
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
@ -18,26 +18,51 @@
|
|||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** ****
|
||||
Type trait: Check if format has static size.
|
||||
*/
|
||||
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>
|
||||
class MFormat
|
||||
{
|
||||
public:
|
||||
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);
|
||||
|
||||
/** 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>
|
||||
constexpr MFormat(const FormatT& f);
|
||||
|
||||
/** Get underlying array. */
|
||||
const Arr<UPos,N>& all() const;
|
||||
|
||||
/** Get format size. */
|
||||
constexpr decltype(auto) size() const;
|
||||
|
||||
/** Get format element.
|
||||
@param i CSizeT indicating static element position
|
||||
*/
|
||||
template <SizeT I>
|
||||
constexpr decltype(auto) get(CSizeT<I> i) const;
|
||||
|
||||
/** Get format element.
|
||||
@param i CSizeT indicating static element position
|
||||
*/
|
||||
template <SizeT I>
|
||||
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; };
|
||||
|
||||
/** ****
|
||||
Multi index format of static size.
|
||||
Wrapper of standard tuple of position types.
|
||||
@tparam PosT Position types.
|
||||
*/
|
||||
template <class... PosT>
|
||||
class GMFormat
|
||||
{
|
||||
public:
|
||||
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);
|
||||
|
||||
/** Construct from tuple (move).
|
||||
@param b Input tuple.
|
||||
*/
|
||||
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>
|
||||
constexpr GMFormat(const FormatT& f);
|
||||
|
||||
/** Get underlying tuple. */
|
||||
const Tuple<PosT...>& all() const;
|
||||
|
||||
/** Get format size. */
|
||||
constexpr decltype(auto) size() const;
|
||||
|
||||
/** Get format element.
|
||||
@param i CSizeT indicating static element position
|
||||
*/
|
||||
template <SizeT I>
|
||||
constexpr decltype(auto) get(CSizeT<I> i) const;
|
||||
|
||||
/** Get format element.
|
||||
@param i CSizeT indicating static element position
|
||||
*/
|
||||
template <SizeT I>
|
||||
constexpr decltype(auto) operator[](CSizeT<I> i) const;
|
||||
|
||||
|
@ -74,38 +130,76 @@ namespace CNORXZ
|
|||
Tuple<PosT...> mB;
|
||||
};
|
||||
|
||||
/** Create GMFormat from position types.
|
||||
@param ps Position types.
|
||||
*/
|
||||
template <class... PosT>
|
||||
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; };
|
||||
|
||||
/** ****
|
||||
Multi index format of variable size
|
||||
Wrapper of standard vector of UPos.
|
||||
*/
|
||||
class YFormat
|
||||
{
|
||||
public:
|
||||
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);
|
||||
|
||||
/** Construct from format of arbitrary type.
|
||||
@param f Input format.
|
||||
*/
|
||||
template <class FormatT>
|
||||
YFormat(const FormatT& f);
|
||||
|
||||
/** Get underlying vector. */
|
||||
const Vector<UPos>& all() const;
|
||||
|
||||
/** Get format size. */
|
||||
SizeT size() const;
|
||||
|
||||
/** Get format element.
|
||||
@param i CSizeT indicating static element position
|
||||
*/
|
||||
template <SizeT I>
|
||||
const UPos& get(CSizeT<I> i) const;
|
||||
|
||||
/** Get format element.
|
||||
@param i CSizeT indicating static element position
|
||||
*/
|
||||
template <SizeT I>
|
||||
const UPos& operator[](CSizeT<I> i) const;
|
||||
|
||||
/** Get format element.
|
||||
@param i E element position
|
||||
*/
|
||||
const UPos& get(SizeT i) const;
|
||||
|
||||
/** Get format element.
|
||||
@param i E element position
|
||||
*/
|
||||
const UPos& operator[](SizeT i) const;
|
||||
|
||||
private:
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
/**
|
||||
|
||||
@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
|
||||
|
||||
**/
|
||||
|
@ -35,30 +36,71 @@ namespace CNORXZ
|
|||
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>
|
||||
inline decltype(auto) operator*(const IndexInterface<I1,Meta1>& a,
|
||||
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>
|
||||
inline decltype(auto) operator*(const IndexInterface<I1,Meta1>& a,
|
||||
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>
|
||||
inline decltype(auto) operator*(const SPack<Indices...>& a,
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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);
|
||||
|
||||
|
||||
/** 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>
|
||||
decltype(auto) iptrMul(const Sptr<I1>& a, const Sptr<I2>& b);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
@file include/ranges/index_traits.h
|
||||
@brief index traits
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2023 Christian Zimmermann. All rights reserved.
|
||||
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
|
||||
@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
|
||||
|
||||
**/
|
||||
|
@ -20,7 +22,11 @@
|
|||
|
||||
namespace CNORXZ
|
||||
{
|
||||
// static label to enforce loop unrolling
|
||||
/** ****
|
||||
Statically labeled index.
|
||||
@tparam Index Underlying index.
|
||||
@tparam L Static label.
|
||||
*/
|
||||
template <class Index, SizeT L>
|
||||
class LIndex : public Index
|
||||
{
|
||||
|
@ -28,14 +34,25 @@ namespace CNORXZ
|
|||
typedef typename Index::IB IB;
|
||||
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);
|
||||
|
||||
/** @copydoc IndexInterface::id()
|
||||
Specialization: Static id equals L.
|
||||
*/
|
||||
IndexId<L> id() const;
|
||||
|
||||
/** @copydoc IndexInterface::stepSize()
|
||||
Specialization: stepSize may be static.
|
||||
*/
|
||||
template <SizeT I>
|
||||
decltype(auto) stepSize(const IndexId<I>& id) const;
|
||||
|
||||
/** @copydoc IndexInterface::stepSize() */
|
||||
template <class Xpr, class F>
|
||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||
|
||||
|
@ -43,6 +60,10 @@ namespace CNORXZ
|
|||
Sptr<Index> mI;
|
||||
};
|
||||
|
||||
/** ***
|
||||
LIndex is an index
|
||||
@see is_index
|
||||
*/
|
||||
template <class Index, SizeT L>
|
||||
struct is_index<LIndex<Index,L>>
|
||||
{
|
||||
|
@ -59,12 +80,27 @@ namespace CNORXZ
|
|||
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>
|
||||
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>
|
||||
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>
|
||||
decltype(auto) lindexPtr(const Sptr<Index>& i, CSizeT<L> l);
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
/**
|
||||
|
||||
@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
|
||||
|
||||
**/
|
||||
|
@ -21,9 +21,9 @@
|
|||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/************************
|
||||
* GMIndex (private) *
|
||||
************************/
|
||||
/*=========================+
|
||||
| GMIndex (private) |
|
||||
+=========================*/
|
||||
|
||||
template <class FormatT, class... Indices>
|
||||
template <SizeT... Is>
|
||||
|
@ -147,9 +147,9 @@ namespace CNORXZ
|
|||
}
|
||||
}
|
||||
|
||||
/***************
|
||||
* GMIndex *
|
||||
***************/
|
||||
/*===============+
|
||||
| GMIndex |
|
||||
+===============*/
|
||||
|
||||
template <class FormatT, class... Indices>
|
||||
constexpr GMIndex<FormatT,Indices...>::GMIndex(const GMIndex& i) :
|
||||
|
@ -551,15 +551,21 @@ namespace CNORXZ
|
|||
GMIndex<FormatT,Indices...>&
|
||||
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){
|
||||
CXZ_ASSERT(CNORXZ::formatIsTrivial(f,s),
|
||||
"cannot reformat MIndex with format type = None");
|
||||
return *this;
|
||||
}
|
||||
else {
|
||||
CXZ_ASSERT(f.size() == s.size(), "input error: f.size() != s.size()");
|
||||
// f: input format
|
||||
// s: input sizes
|
||||
SizeT j = 0;
|
||||
SizeT j0 = 0;
|
||||
SizeT xi = 1;
|
||||
|
@ -590,9 +596,7 @@ namespace CNORXZ
|
|||
mIPack[i]->reformat(nf,ns);
|
||||
}
|
||||
else {
|
||||
// TODO: IMPLEMENT!!!
|
||||
// check trivial format in this partition
|
||||
CXZ_ERROR("reformating with lower-dimensional formats has not yet been implemented");
|
||||
CXZ_ERROR("reformating with lower-dimensional formats is not possible; use sub-indices instead");
|
||||
}
|
||||
}, NoF {});
|
||||
mFormat = FormatT(nformat);
|
||||
|
@ -609,15 +613,6 @@ namespace CNORXZ
|
|||
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>
|
||||
constexpr decltype(auto) mindex(const Sptr<Indices>&... is)
|
||||
{
|
||||
|
@ -648,9 +643,9 @@ namespace CNORXZ
|
|||
return iptrMul(a, b);
|
||||
}
|
||||
|
||||
/*********************
|
||||
* MRangeFactory *
|
||||
*********************/
|
||||
/*=====================+
|
||||
| MRangeFactory |
|
||||
+=====================*/
|
||||
|
||||
template <class... Ranges>
|
||||
MRangeFactory<Ranges...>::MRangeFactory(const Tuple<Sptr<Ranges>...>& rs) :
|
||||
|
@ -679,9 +674,9 @@ namespace CNORXZ
|
|||
}
|
||||
}
|
||||
|
||||
/**************
|
||||
* MRange *
|
||||
**************/
|
||||
/*==============+
|
||||
| MRange |
|
||||
+==============*/
|
||||
|
||||
template <class... Ranges>
|
||||
MRange<Ranges...>::MRange(const Tuple<Sptr<Ranges>...>& rs) :
|
||||
|
@ -699,7 +694,6 @@ namespace CNORXZ
|
|||
template <class... Ranges>
|
||||
MArray<RangePtr> MRange<Ranges...>::sub() const
|
||||
{
|
||||
// TODO: ZRange (meta and index pos static!)
|
||||
if constexpr(NR == 0) {
|
||||
return MArray<RangePtr>();
|
||||
}
|
||||
|
@ -787,9 +781,9 @@ namespace CNORXZ
|
|||
return k;
|
||||
}
|
||||
|
||||
/************************
|
||||
* MRange (private) *
|
||||
************************/
|
||||
/*========================+
|
||||
| MRange (private) |
|
||||
+========================*/
|
||||
|
||||
template <class... Ranges>
|
||||
decltype(auto) MRange<Ranges...>::mkA() const
|
||||
|
@ -798,9 +792,9 @@ namespace CNORXZ
|
|||
[](const auto&... xs) { return Arr<RangePtr,NR> { xs... }; } );
|
||||
}
|
||||
|
||||
/****************************
|
||||
* non-member functions *
|
||||
****************************/
|
||||
/*============================+
|
||||
| non-member functions |
|
||||
+============================*/
|
||||
|
||||
template <class... Ranges>
|
||||
RangePtr mrange(const Sptr<Ranges>&... rs)
|
||||
|
|
|
@ -2,10 +2,15 @@
|
|||
/**
|
||||
|
||||
@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
|
||||
|
||||
**/
|
||||
|
@ -22,8 +27,13 @@
|
|||
|
||||
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>
|
||||
class GMIndex : public IndexInterface<GMIndex<FormatT,Indices...>,
|
||||
Tuple<typename Indices::MetaType...> >
|
||||
|
@ -32,75 +42,146 @@ namespace CNORXZ
|
|||
|
||||
typedef IndexInterface<GMIndex<FormatT,Indices...>,
|
||||
Tuple<typename Indices::MetaType...>> IB;
|
||||
//typedef Tuple<Sptr<Indices>...> IndexPack;
|
||||
typedef Tuple<typename Indices::MetaType...> MetaType;
|
||||
typedef MRange<typename Indices::RangeType...> RangeType;
|
||||
static constexpr SizeT NI = sizeof...(Indices);
|
||||
|
||||
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
||||
|
||||
/** Default constructor. */
|
||||
constexpr GMIndex() = default;
|
||||
|
||||
/** Move constructor (default). */
|
||||
constexpr GMIndex(GMIndex&& i) = default;
|
||||
|
||||
/** Move assignment (default). */
|
||||
constexpr GMIndex& operator=(GMIndex&& i) = default;
|
||||
// no defaults:
|
||||
|
||||
/** Copy constructor (no default, copy sub-index instances). */
|
||||
constexpr GMIndex(const GMIndex& i);
|
||||
|
||||
/** Copy assignment (no default, copy sub-index instances). */
|
||||
constexpr GMIndex& operator=(const GMIndex& i);
|
||||
|
||||
/** Construct from index pack. */
|
||||
constexpr GMIndex(const SPack<Indices...>& pack);
|
||||
|
||||
/** Construct from index pack and format. */
|
||||
constexpr GMIndex(const FormatT& format, const SPack<Indices...>& pack);
|
||||
|
||||
/** Construct from index pointers. */
|
||||
constexpr GMIndex(const Sptr<Indices>&... is);
|
||||
|
||||
/** Construct from index pointers and format. */
|
||||
constexpr GMIndex(const FormatT& format, const Sptr<Indices>&... is);
|
||||
|
||||
/** Construct from range. */
|
||||
constexpr GMIndex(const RangePtr& range, SizeT lexpos = 0);
|
||||
|
||||
/** Construct from range and format. */
|
||||
constexpr GMIndex(const RangePtr& range, const FormatT& format, SizeT lexpos = 0);
|
||||
|
||||
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||
GMIndex& operator=(SizeT pos);
|
||||
|
||||
/** @copydoc IndexInterface::operator++() */
|
||||
GMIndex& operator++();
|
||||
|
||||
/** @copydoc IndexInterface::operator--() */
|
||||
GMIndex& operator--();
|
||||
|
||||
/** @copydoc IndexInterface::operator+() */
|
||||
GMIndex operator+(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-() */
|
||||
GMIndex operator-(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-(CIndex) */
|
||||
SizeT operator-(const GMIndex& i) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator+=() */
|
||||
GMIndex& operator+=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::operator-=() */
|
||||
GMIndex& operator-=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::lex() */
|
||||
SizeT lex() const;
|
||||
|
||||
/** @copydoc IndexInterface::pmax() */
|
||||
constexpr decltype(auto) pmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::lmax() */
|
||||
constexpr decltype(auto) lmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::id() */
|
||||
IndexId<0> id() const;
|
||||
|
||||
/** @copydoc IndexInterface::operator*() */
|
||||
MetaType operator*() const;
|
||||
|
||||
/** @copydoc IndexInterface::dim() */
|
||||
constexpr SizeT dim() const;
|
||||
|
||||
/** @copydoc IndexInterface::range() */
|
||||
Sptr<RangeType> range() const;
|
||||
|
||||
/** @copydoc IndexInterface::stepSize() */
|
||||
template <SizeT I>
|
||||
decltype(auto) stepSize(const IndexId<I>& id) const;
|
||||
|
||||
/** @copydoc IndexInterface::stringMeta() */
|
||||
String stringMeta() const;
|
||||
|
||||
/** @copydoc IndexInterface::meta() */
|
||||
MetaType meta() const;
|
||||
|
||||
/** @copydoc IndexInterface::at() */
|
||||
GMIndex& at(const MetaType& metaPos);
|
||||
decltype(auto) xpr(const Sptr<MIndex<Indices...>>& _this) const;
|
||||
|
||||
template <class Xpr, class F>
|
||||
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;
|
||||
/** @copydoc IndexInterface::prange() */
|
||||
RangePtr prange(const GMIndex<FormatT,Indices...>& last) const;
|
||||
|
||||
/** @copydoc IndexInterface::deepFormat() */
|
||||
auto deepFormat() const;
|
||||
|
||||
/** @copydoc IndexInterface::deepMax() */
|
||||
auto deepMax() const;
|
||||
|
||||
/** @copydoc IndexInterface::reformat() */
|
||||
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() */
|
||||
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:
|
||||
template <SizeT... Is>
|
||||
static constexpr decltype(auto) mkLexFormat(const SPack<Indices...>& ipack, Isq<Is...> is);
|
||||
|
@ -135,53 +216,114 @@ namespace CNORXZ
|
|||
PMaxT mPMax;
|
||||
};
|
||||
|
||||
template <class BT1, class BT2, class... Indices>
|
||||
decltype(auto) replaceFormat(const BT1& bs1, const Sptr<GMIndex<BT2,Indices...>>& gmi);
|
||||
|
||||
template <class... Indices>
|
||||
struct index_has_const_size<MIndex<Indices...>>
|
||||
/** ****
|
||||
Specialization of index_has_const_size for GMIndex.
|
||||
@see index_has_const_size
|
||||
*/
|
||||
template <class FormatT, class... Indices>
|
||||
struct index_has_const_size<GMIndex<FormatT,Indices...>>
|
||||
{ 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 * ...); };
|
||||
|
||||
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); };
|
||||
|
||||
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; };
|
||||
|
||||
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; };
|
||||
|
||||
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; };
|
||||
|
||||
/** ***
|
||||
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>
|
||||
constexpr decltype(auto) mindex(const Sptr<Indices>&... is);
|
||||
|
||||
/** Create MIndex from index pack.
|
||||
@param pack Pack of input indices.
|
||||
*/
|
||||
template <class... Indices>
|
||||
constexpr decltype(auto) mindex(const SPack<Indices...>& pack);
|
||||
|
||||
/** Create pointer to MIndex from index pack.
|
||||
@param pack Pack of input indices.
|
||||
*/
|
||||
template <class... Indices>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
class MRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
public:
|
||||
|
||||
/** Construct and setup factory.
|
||||
@param rs Tuple of sub-ranges.
|
||||
*/
|
||||
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);
|
||||
|
||||
private:
|
||||
|
@ -192,6 +334,10 @@ namespace CNORXZ
|
|||
RangePtr mRef;
|
||||
};
|
||||
|
||||
/** ****
|
||||
Multi Range with compile-time fixed number of sub-ranges
|
||||
of compile-time fixed type.
|
||||
*/
|
||||
template <class... Ranges>
|
||||
class MRange : public RangeInterface<MRange<Ranges...>>
|
||||
{
|
||||
|
@ -212,18 +358,34 @@ namespace CNORXZ
|
|||
virtual const TypeInfo& metaType() const override final;
|
||||
virtual RangePtr extend(const RangePtr& r) const override final;
|
||||
|
||||
/** Get sub-ranges. */
|
||||
decltype(auto) space() const;
|
||||
|
||||
/** Get sub-range.
|
||||
@param pos Position of the sub-range.
|
||||
*/
|
||||
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;
|
||||
|
||||
protected:
|
||||
|
||||
/** Dafault constructor */
|
||||
MRange() = default;
|
||||
|
||||
MRange(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);
|
||||
|
||||
Tuple<Sptr<Ranges>...> mRs;
|
||||
Arr<RangePtr,NR> mA;
|
||||
Tuple<Sptr<Ranges>...> mRs; /**< Tuple of pointers to sub-ranges. */
|
||||
Arr<RangePtr,NR> mA; /**< Array of abstract base pointers to sub-ranges. Redundant to mRs */
|
||||
|
||||
virtual Vector<Uuid> key() const override final;
|
||||
private:
|
||||
|
@ -231,24 +393,22 @@ namespace CNORXZ
|
|||
decltype(auto) mkA() const;
|
||||
};
|
||||
|
||||
/** Create MRange pointer.
|
||||
@param rs Pointer to sub-ranges.
|
||||
*/
|
||||
template <class... Ranges>
|
||||
RangePtr mrange(const Sptr<Ranges>&... rs);
|
||||
|
||||
/** ****
|
||||
Specialization of RangeCast for MRange.
|
||||
@see RangeCast.
|
||||
*/
|
||||
template <class... Ranges>
|
||||
struct RangeCast<MRange<Ranges...>>
|
||||
{
|
||||
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
|
||||
@brief ...
|
||||
@brief PRange, PRangeFactory and PIndex implementations.
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
@ -18,9 +17,9 @@
|
|||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/**************
|
||||
* PIndex *
|
||||
**************/
|
||||
/*============+
|
||||
| PIndex |
|
||||
+============*/
|
||||
|
||||
template <class IndexT>
|
||||
PIndex<IndexT>::PIndex(const RangePtr& range, SizeT pos) :
|
||||
|
@ -206,9 +205,7 @@ namespace CNORXZ
|
|||
template <class IndexT>
|
||||
decltype(auto) PIndex<IndexT>::xpr(const Sptr<PIndex<IndexT>>& _this) const
|
||||
{
|
||||
CXZ_ERROR("implement!!!");
|
||||
//return poperation( _this, mOrig, mRangePtr->parts(), mOrig->xpr(mOrig) );
|
||||
return mOrig->xpr(mOrig);
|
||||
return poproot( _this, mRangePtr->parts(), mOrig->xpr(mOrig) );
|
||||
}
|
||||
|
||||
template <class IndexT>
|
||||
|
@ -246,9 +243,9 @@ namespace CNORXZ
|
|||
return mOrig;
|
||||
}
|
||||
|
||||
/************************
|
||||
* PIndex (private) *
|
||||
************************/
|
||||
/*======================+
|
||||
| PIndex (private) |
|
||||
+======================*/
|
||||
|
||||
template <class IndexT>
|
||||
void PIndex<IndexT>::mkPos()
|
||||
|
@ -264,9 +261,9 @@ namespace CNORXZ
|
|||
CXZ_ERROR("meta position '" << toString(mOrig->meta()) << "' not part of range");
|
||||
}
|
||||
|
||||
/***************************
|
||||
* PIndex (non-member) *
|
||||
***************************/
|
||||
/*=========================+
|
||||
| PIndex (non-member) |
|
||||
+=========================*/
|
||||
|
||||
template <class I, class I1>
|
||||
decltype(auto) operator*(const Sptr<PIndex<I>>& a, const Sptr<I1>& b)
|
||||
|
@ -274,9 +271,9 @@ namespace CNORXZ
|
|||
return iptrMul(a, b);
|
||||
}
|
||||
|
||||
/*********************
|
||||
* PRangeFactory *
|
||||
*********************/
|
||||
/*===================+
|
||||
| PRangeFactory |
|
||||
+===================*/
|
||||
|
||||
template <class RangeT>
|
||||
PRangeFactory<RangeT>::PRangeFactory(const Sptr<RangeT>& range, const Vector<SizeT>& _parts) :
|
||||
|
@ -301,9 +298,9 @@ namespace CNORXZ
|
|||
}
|
||||
}
|
||||
|
||||
/**************
|
||||
* PRange *
|
||||
**************/
|
||||
/*============+
|
||||
| PRange |
|
||||
+============*/
|
||||
|
||||
template <class RangeT>
|
||||
SizeT PRange<RangeT>::size() const
|
||||
|
@ -338,10 +335,19 @@ namespace CNORXZ
|
|||
template <class RangeT>
|
||||
RangePtr PRange<RangeT>::extend(const RangePtr& r) const
|
||||
{
|
||||
CXZ_ERROR("implement!!!");
|
||||
// if r is PRange of same Range, then just add parts
|
||||
// else derive and add meta of r
|
||||
return nullptr;
|
||||
if(r->type() == type()){
|
||||
Sptr<PRange<RangeT>> rx = std::dynamic_pointer_cast<PRange<RangeT>>(r);
|
||||
if(rx->orig() == orig()){
|
||||
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>
|
||||
|
@ -361,16 +367,17 @@ namespace CNORXZ
|
|||
{
|
||||
Vector<MetaType> meta(this->size());
|
||||
auto i = mRange->begin();
|
||||
SizeT j = 0;
|
||||
for(const auto& p: mParts){
|
||||
meta = *(i = p);
|
||||
meta[j++] = *(i = p);
|
||||
}
|
||||
return URangeFactory<MetaType>( meta ).create();
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* PRange (private) *
|
||||
************************/
|
||||
/*======================+
|
||||
| PRange (private) |
|
||||
+======================*/
|
||||
|
||||
template <class RangeT>
|
||||
PRange<RangeT>::PRange(const Sptr<RangeT>& range, const Vector<SizeT>& _parts) :
|
||||
|
@ -386,9 +393,9 @@ namespace CNORXZ
|
|||
return Vector<Uuid> { mRange->id() };
|
||||
}
|
||||
|
||||
/****************************
|
||||
* non-member functions *
|
||||
****************************/
|
||||
/*==========================+
|
||||
| non-member functions |
|
||||
+==========================*/
|
||||
|
||||
template <class RangeT>
|
||||
RangePtr prange(const Sptr<RangeT>& range, const Vector<SizeT>& parts)
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
/**
|
||||
|
||||
@file include/ranges/prange.h
|
||||
@brief ...
|
||||
@brief PRange, PRangeFactory and PIndex declaration.
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
@ -20,7 +19,10 @@
|
|||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
/** ****
|
||||
Index specific for PRange.
|
||||
@tparam IndexT Full index type.
|
||||
*/
|
||||
template <class IndexT>
|
||||
class PIndex : public IndexInterface<PIndex<IndexT>,typename IndexT::MetaType>
|
||||
{
|
||||
|
@ -30,51 +32,105 @@ namespace CNORXZ
|
|||
typedef PRange<typename IndexT::RangeType> RangeType;
|
||||
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);
|
||||
|
||||
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||
PIndex& operator=(SizeT lexpos);
|
||||
|
||||
/** @copydoc IndexInterface::operator++() */
|
||||
PIndex& operator++();
|
||||
|
||||
/** @copydoc IndexInterface::operator--() */
|
||||
PIndex& operator--();
|
||||
|
||||
/** @copydoc IndexInterface::operator+() */
|
||||
PIndex operator+(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-() */
|
||||
PIndex operator-(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-(PIndex) */
|
||||
SizeT operator-(const PIndex& i) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator+=() */
|
||||
PIndex& operator+=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::operator-=() */
|
||||
PIndex& operator-=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::lex() */
|
||||
SizeT lex() const;
|
||||
|
||||
/** @copydoc IndexInterface::pmax() */
|
||||
UPos pmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::lmax() */
|
||||
UPos lmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::id() */
|
||||
IndexId<0> id() const;
|
||||
|
||||
/** @copydoc IndexInterface::operator*() */
|
||||
decltype(auto) operator*() const;
|
||||
|
||||
/** @copydoc IndexInterface::dim() */
|
||||
SizeT dim() const;
|
||||
|
||||
/** @copydoc IndexInterface::range() */
|
||||
Sptr<RangeType> range() const;
|
||||
|
||||
/** @copydoc IndexInterface::stepSize() */
|
||||
template <SizeT I>
|
||||
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;
|
||||
|
||||
/** @copydoc IndexInterface::deepFormat() */
|
||||
decltype(auto) deepFormat() const;
|
||||
|
||||
/** @copydoc IndexInterface::deepMax() */
|
||||
decltype(auto) deepMax() const;
|
||||
|
||||
/** @copydoc IndexInterface::reformat() */
|
||||
PIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
||||
|
||||
String stringMeta() const;
|
||||
decltype(auto) meta() const;
|
||||
PIndex& at(const MetaType& metaPos);
|
||||
decltype(auto) xpr(const Sptr<PIndex<IndexT>>& _this) const;
|
||||
|
||||
/** @copydoc IndexInterface::ifor() */
|
||||
template <class Xpr, class F>
|
||||
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() */
|
||||
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:
|
||||
Sptr<RangeType> mRangePtr;
|
||||
Sptr<IndexT> mOrig;
|
||||
|
@ -82,14 +138,31 @@ namespace CNORXZ
|
|||
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>
|
||||
decltype(auto) operator*(const Sptr<PIndex<I>>& a, const Sptr<I1>& b);
|
||||
|
||||
/** ****
|
||||
Specific factory for PRange.
|
||||
*/
|
||||
template <class RangeT>
|
||||
class PRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
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);
|
||||
|
||||
/** 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);
|
||||
|
||||
private:
|
||||
|
@ -100,6 +173,13 @@ namespace CNORXZ
|
|||
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>
|
||||
class PRange : public RangeInterface<PRange<RangeT>>
|
||||
{
|
||||
|
@ -117,8 +197,20 @@ namespace CNORXZ
|
|||
virtual const TypeInfo& metaType() 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;
|
||||
|
||||
/** Get the parts.
|
||||
@return Integer vector indicating the parts contained by the PRange w.r.t. the full range.
|
||||
*/
|
||||
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;
|
||||
|
||||
private:
|
||||
|
@ -133,6 +225,11 @@ namespace CNORXZ
|
|||
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>
|
||||
RangePtr prange(const Sptr<RangeT>& range, const Vector<SizeT>& parts);
|
||||
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
/**
|
||||
|
||||
@file include/ranges/ranges.h
|
||||
@brief ...
|
||||
@brief Ranges main header
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
/**
|
||||
|
||||
@file include/ranges/srange.h
|
||||
@brief ...
|
||||
@brief SRange, SRangeFactory and SIndex declaration.
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
@ -20,6 +19,11 @@
|
|||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** ****
|
||||
Specific index for SRange.
|
||||
@tparam MetaT Meta data type.
|
||||
@tparam S Static size of the range.
|
||||
*/
|
||||
template <typename MetaT, SizeT S>
|
||||
class SIndex : public IndexInterface<SIndex<MetaT,S>,MetaT>
|
||||
{
|
||||
|
@ -29,43 +33,88 @@ namespace CNORXZ
|
|||
typedef MetaT 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);
|
||||
|
||||
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||
SIndex& operator=(SizeT lexpos);
|
||||
|
||||
/** @copydoc IndexInterface::operator++() */
|
||||
SIndex& operator++();
|
||||
|
||||
/** @copydoc IndexInterface::operator--() */
|
||||
SIndex& operator--();
|
||||
|
||||
/** @copydoc IndexInterface::operator+() */
|
||||
SIndex operator+(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-() */
|
||||
SIndex operator-(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-(SIndex) */
|
||||
SizeT operator-(const SIndex& i) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator+=() */
|
||||
SIndex& operator+=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::operator-=() */
|
||||
SIndex& operator-=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::lex() */
|
||||
SizeT lex() const;
|
||||
|
||||
/** @copydoc IndexInterface::pmax() */
|
||||
SPos<S> pmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::lmax() */
|
||||
SPos<S> lmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::id() */
|
||||
IndexId<0> id() const;
|
||||
|
||||
/** @copydoc IndexInterface::operator*() */
|
||||
const MetaT& operator*() const;
|
||||
|
||||
/** @copydoc IndexInterface::dim() */
|
||||
SizeT dim() const; // = 1
|
||||
|
||||
/** @copydoc IndexInterface::range() */
|
||||
Sptr<RangeType> range() const;
|
||||
|
||||
/** @copydoc IndexInterface::stepSize() */
|
||||
template <SizeT I>
|
||||
UPos stepSize(const IndexId<I>& id) const;
|
||||
|
||||
/** @copydoc IndexInterface::stringMeta() */
|
||||
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;
|
||||
|
||||
/** @copydoc IndexInterface::deepFormat() */
|
||||
SizeT deepFormat() const;
|
||||
|
||||
/** @copydoc IndexInterface::deepMax() */
|
||||
SizeT deepMax() const;
|
||||
|
||||
/** @copydoc IndexInterface::reformat() */
|
||||
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>
|
||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||
|
||||
|
@ -77,16 +126,43 @@ namespace CNORXZ
|
|||
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>
|
||||
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>
|
||||
class SRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
public:
|
||||
|
||||
/** Construct and setup factory.
|
||||
@param space Meta data array defining the range.
|
||||
*/
|
||||
SRangeFactory(const Arr<MetaT,S>& space);
|
||||
|
||||
/** Construct and setup factory.
|
||||
@param space Meta data array defining the range (move).
|
||||
*/
|
||||
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);
|
||||
|
||||
/** 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);
|
||||
|
||||
private:
|
||||
|
@ -97,6 +173,12 @@ namespace CNORXZ
|
|||
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>
|
||||
class SRange : public RangeInterface<SRange<MetaT,S>>
|
||||
{
|
||||
|
@ -114,8 +196,19 @@ namespace CNORXZ
|
|||
virtual const TypeInfo& metaType() 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;
|
||||
|
||||
/** Get underlying meta data array.
|
||||
@return Pointer to first position of meta data array.
|
||||
*/
|
||||
const MetaT* get() const;
|
||||
|
||||
/** return position for given meta data.
|
||||
@param metaPos meta data, size type
|
||||
*/
|
||||
SizeT getMeta(const MetaT& metaPos) const;
|
||||
|
||||
private:
|
||||
|
@ -132,9 +225,16 @@ namespace CNORXZ
|
|||
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>
|
||||
struct RangeCast<SRange<MetaT,S>>
|
||||
{
|
||||
/** cast the range */
|
||||
static Sptr<SRange<MetaT,S>> func(const RangePtr& r);
|
||||
};
|
||||
|
||||
|
|
|
@ -299,7 +299,10 @@ namespace CNORXZ
|
|||
{
|
||||
auto b = mSpace.begin();
|
||||
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>
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
/**
|
||||
|
||||
@file include/ranges/urange.h
|
||||
@brief ...
|
||||
@brief URange, URangeFactory and UIndex declaration.
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
@ -23,6 +22,10 @@
|
|||
namespace CNORXZ
|
||||
{
|
||||
|
||||
/** ****
|
||||
Specific index for URange.
|
||||
@tparam MetaT Meta data type.
|
||||
*/
|
||||
template <typename MetaT>
|
||||
class UIndex : public IndexInterface<UIndex<MetaT>,MetaT>
|
||||
{
|
||||
|
@ -33,51 +36,94 @@ namespace CNORXZ
|
|||
typedef MetaT 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);
|
||||
|
||||
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||
UIndex& operator=(SizeT lexpos);
|
||||
|
||||
/** @copydoc IndexInterface::operator++() */
|
||||
UIndex& operator++();
|
||||
|
||||
/** @copydoc IndexInterface::operator--() */
|
||||
UIndex& operator--();
|
||||
|
||||
/** @copydoc IndexInterface::operator+() */
|
||||
UIndex operator+(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-() */
|
||||
UIndex operator-(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-(UIndex) */
|
||||
SizeT operator-(const UIndex& i) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator+=() */
|
||||
UIndex& operator+=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::operator-=() */
|
||||
UIndex& operator-=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::lex() */
|
||||
SizeT lex() const;
|
||||
|
||||
/** @copydoc IndexInterface::pmax() */
|
||||
UPos pmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::lmax() */
|
||||
UPos lmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::id() */
|
||||
IndexId<0> id() const;
|
||||
|
||||
/** @copydoc IndexInterface::operator*() */
|
||||
const MetaT& operator*() const;
|
||||
|
||||
/** @copydoc IndexInterface::dim() */
|
||||
SizeT dim() const; // = 1
|
||||
|
||||
/** @copydoc IndexInterface::range() */
|
||||
Sptr<RangeType> range() const;
|
||||
|
||||
/** @copydoc IndexInterface::stepSize() */
|
||||
template <SizeT I>
|
||||
decltype(auto) stepSize(const IndexId<I>& id) const;
|
||||
|
||||
/** @copydoc IndexInterface::stringMeta() */
|
||||
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;
|
||||
|
||||
/** @copydoc IndexInterface::deepFormat() */
|
||||
SizeT deepFormat() const;
|
||||
|
||||
/** @copydoc IndexInterface::deepMax() */
|
||||
SizeT deepMax() const;
|
||||
|
||||
/** @copydoc IndexInterface::reformat() */
|
||||
UIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
||||
|
||||
/** @copydoc IndexInterface::ifor() */
|
||||
template <class Xpr, class F>
|
||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||
|
||||
/** @copydoc IndexInterface::formatIsTrivial() */
|
||||
bool formatIsTrivial() const;
|
||||
|
||||
/** @copydoc IndexInterface::xpr() */
|
||||
decltype(auto) xpr(const Sptr<UIndex<MetaType>>& _this) const;
|
||||
|
||||
private:
|
||||
Sptr<RangeType> mRangePtr;
|
||||
const MetaT* mMetaPtr;
|
||||
|
@ -86,26 +132,39 @@ namespace CNORXZ
|
|||
template <typename MetaT>
|
||||
void swap(UIndex<MetaT>& a, UIndex<MetaT>& b) { a.swap(b); }
|
||||
|
||||
template <typename MetaType, class I1>
|
||||
decltype(auto) operator*(const Sptr<UIndex<MetaType>>& a, const Sptr<I1>& b);
|
||||
/** Make index pack of a UIndex and another index.
|
||||
@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
|
||||
{
|
||||
public:
|
||||
URangeFactory(const Vector<MetaType>& space);
|
||||
URangeFactory(Vector<MetaType>&& space);
|
||||
URangeFactory(const Vector<MetaType>& space, const RangePtr& ref);
|
||||
URangeFactory(Vector<MetaType>&& space, const RangePtr& ref);
|
||||
URangeFactory(const Vector<MetaT>& space);
|
||||
URangeFactory(Vector<MetaT>&& space);
|
||||
URangeFactory(const Vector<MetaT>& space, const RangePtr& ref);
|
||||
URangeFactory(Vector<MetaT>&& space, const RangePtr& ref);
|
||||
|
||||
private:
|
||||
URangeFactory() = default;
|
||||
virtual void make() override final;
|
||||
|
||||
Vector<MetaType> mSpace;
|
||||
Vector<MetaT> mSpace;
|
||||
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>
|
||||
class URange : public RangeInterface<URange<MetaT>>
|
||||
{
|
||||
|
@ -123,8 +182,21 @@ namespace CNORXZ
|
|||
virtual const TypeInfo& metaType() 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;
|
||||
|
||||
/** Get meta data array.
|
||||
@return Pointer to first element of the underlying meta data array.
|
||||
*/
|
||||
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;
|
||||
|
||||
private:
|
||||
|
@ -141,12 +213,21 @@ namespace CNORXZ
|
|||
SERIALIZATION_FUNCTIONS_NOPUB;
|
||||
};
|
||||
|
||||
/** ***
|
||||
Specialize RangeCast for casts to URange
|
||||
@see RangeCast
|
||||
*/
|
||||
template <typename MetaType>
|
||||
struct RangeCast<URange<MetaType>>
|
||||
{
|
||||
/** cast the range */
|
||||
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>
|
||||
RangePtr urange(const Vector<MetaT>& space);
|
||||
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
/**
|
||||
|
||||
@file include/ranges/xindex.h
|
||||
@brief ...
|
||||
@brief XIndexBase and XIndex template declaration.
|
||||
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
@ -20,66 +19,145 @@
|
|||
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
||||
//typedef DType MetaType;
|
||||
DEFAULT_MEMBERS(XIndexBase); /**< default constructors and assignments */
|
||||
|
||||
DEFAULT_MEMBERS(XIndexBase);
|
||||
/** Virtual default destructor */
|
||||
virtual ~XIndexBase() = default;
|
||||
|
||||
/** Copy this index
|
||||
@return Pointer to the copy.
|
||||
*/
|
||||
virtual XIndexPtr copy() const = 0;
|
||||
|
||||
/** Current position.
|
||||
@return Current position.
|
||||
*/
|
||||
virtual SizeT pos() const = 0;
|
||||
|
||||
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||
virtual XIndexBase& operator=(SizeT lexpos) = 0;
|
||||
|
||||
/** @copydoc IndexInterface::operator++() */
|
||||
virtual XIndexBase& operator++() = 0;
|
||||
|
||||
/** @copydoc IndexInterface::operator--() */
|
||||
virtual XIndexBase& operator--() = 0;
|
||||
|
||||
/** @copydoc IndexInterface::operator+() */
|
||||
virtual XIndexPtr operator+(Int n) const = 0;
|
||||
|
||||
/** @copydoc IndexInterface::operator-() */
|
||||
virtual XIndexPtr operator-(Int n) const = 0;
|
||||
|
||||
/** @copydoc IndexInterface::operator-(UIndex) */
|
||||
virtual SizeT operator-(const XIndexBase& i) const = 0;
|
||||
|
||||
/** @copydoc IndexInterface::operator+=() */
|
||||
virtual XIndexBase& operator+=(Int n) = 0;
|
||||
|
||||
/** @copydoc IndexInterface::operator-=() */
|
||||
virtual XIndexBase& operator-=(Int n) = 0;
|
||||
|
||||
/** @copydoc IndexInterface::lex() */
|
||||
virtual SizeT lex() const = 0;
|
||||
|
||||
/** @copydoc IndexInterface::pmax() */
|
||||
virtual UPos pmax() const = 0;
|
||||
|
||||
/** @copydoc IndexInterface::lmax() */
|
||||
virtual UPos lmax() const = 0;
|
||||
|
||||
/** @copydoc IndexInterface::id() */
|
||||
virtual IndexId<0> id() const = 0;
|
||||
|
||||
/** @copydoc IndexInterface::operator*() */
|
||||
virtual DType operator*() const = 0;
|
||||
|
||||
/** @copydoc IndexInterface::dim() */
|
||||
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;
|
||||
|
||||
/** @copydoc IndexInterface::meta() */
|
||||
virtual DType meta() const = 0;
|
||||
|
||||
/** @copydoc IndexInterface::at() */
|
||||
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;
|
||||
|
||||
/** @copydoc IndexInterface::formatIsTrivial() */
|
||||
virtual bool formatIsTrivial() const = 0;
|
||||
};
|
||||
|
||||
//Sptr<XIndexBase>& operator++(Sptr<XIndexBase>& i);
|
||||
//Sptr<XIndexBase>& operator--(Sptr<XIndexBase>& i);
|
||||
|
||||
// MultiIndex Wrapper:
|
||||
/** ****
|
||||
Index Wrapper.
|
||||
@tparam Index Type of index to be wrapped.
|
||||
@tparam Meta Meta data type of wrapped index.
|
||||
*/
|
||||
template <class Index, typename Meta>
|
||||
class XIndex : public XIndexBase
|
||||
{
|
||||
public:
|
||||
|
||||
DEFAULT_C(XIndex);
|
||||
// no default copy/assignment (have to copy objects in shared ptr)
|
||||
DEFAULT_C(XIndex); /** < default constructor. */
|
||||
|
||||
/** Copy constructor.
|
||||
No default: have to copy objects in shared ptr.
|
||||
*/
|
||||
XIndex(const XIndex& i);
|
||||
|
||||
/** Move constructor.
|
||||
*/
|
||||
XIndex(XIndex&& i);
|
||||
|
||||
/** Copy assignment.
|
||||
No default: have to copy objects in shared ptr.
|
||||
*/
|
||||
XIndex& operator=(const XIndex& i);
|
||||
|
||||
/** Move assignment.
|
||||
*/
|
||||
XIndex& operator=(XIndex&& i);
|
||||
|
||||
/** Construct.
|
||||
@param i Pointer to index to be wrapped.
|
||||
*/
|
||||
XIndex(const IndexPtr<Index,Meta>& i);
|
||||
|
||||
/** Construct.
|
||||
@param i Index to be wrapped.
|
||||
*/
|
||||
XIndex(const IndexInterface<Index,Meta>& i);
|
||||
|
||||
virtual XIndexPtr copy() const override final;
|
||||
|
@ -104,20 +182,24 @@ namespace CNORXZ
|
|||
virtual SizeT dim() const override final;
|
||||
virtual RangePtr range() 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 Vector<SizeT> deepFormat() const override final;
|
||||
virtual Vector<SizeT> deepMax() const 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 bool formatIsTrivial() const override final;
|
||||
|
||||
/** Get underlying index instance.
|
||||
@return Reference to index.
|
||||
*/
|
||||
Index& get();
|
||||
|
||||
/** Get underlying index instance (const).
|
||||
@return Reference to index.
|
||||
*/
|
||||
const Index& get() const;
|
||||
|
||||
private:
|
||||
|
@ -125,13 +207,28 @@ namespace CNORXZ
|
|||
|
||||
};
|
||||
|
||||
/** ****
|
||||
Specialization: has_sub for XIndexBase.
|
||||
XIndexBase can have sub-indices.
|
||||
@see has_sub.
|
||||
*/
|
||||
template <>
|
||||
struct has_sub<XIndexBase>
|
||||
{ static constexpr bool value = true; };
|
||||
|
||||
/** Create XIndex pointer.
|
||||
@param i Index to be wrapped.
|
||||
@return Pointer to created index wrapper.
|
||||
*/
|
||||
template <class Index>
|
||||
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 <>
|
||||
inline XIndexPtr xindexPtr<XIndexBase>(const Sptr<XIndexBase>& i);
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
/**
|
||||
|
||||
@file include/ranges/yrange.h
|
||||
@brief ...
|
||||
|
||||
@brief YRange and YIndex declaration
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
@ -24,6 +23,13 @@
|
|||
|
||||
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>>
|
||||
{
|
||||
public:
|
||||
|
@ -32,59 +38,160 @@ namespace CNORXZ
|
|||
typedef Vector<DType> MetaType;
|
||||
|
||||
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
||||
|
||||
/** Default constructor. */
|
||||
YIndex() = default;
|
||||
|
||||
/** Move constructor. */
|
||||
YIndex(YIndex&& i) = default;
|
||||
|
||||
/** Move assignment. */
|
||||
YIndex& operator=(YIndex&& i) = default;
|
||||
// no defaults:
|
||||
|
||||
/** Copy constructor.
|
||||
No default copy: Have to copy sub-index instances
|
||||
*/
|
||||
YIndex(const YIndex& i);
|
||||
|
||||
/** Copy assigment.
|
||||
No default copy: Have to copy sub-index instances
|
||||
*/
|
||||
YIndex& operator=(const YIndex& i);
|
||||
|
||||
/** Construct from sub-index pointers.
|
||||
@param is Vector of XIndex pointers.
|
||||
*/
|
||||
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);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||
YIndex& operator=(SizeT lexpos);
|
||||
|
||||
/** @copydoc IndexInterface::operator++() */
|
||||
YIndex& operator++();
|
||||
|
||||
/** @copydoc IndexInterface::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;
|
||||
|
||||
/** @copydoc IndexInterface::operator-(CIndex) */
|
||||
SizeT operator-(const YIndex& i) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator+=() */
|
||||
YIndex& operator+=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::operator-=() */
|
||||
YIndex& operator-=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::lex() */
|
||||
SizeT lex() const;
|
||||
|
||||
/** @copydoc IndexInterface::pmax() */
|
||||
UPos pmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::lmax() */
|
||||
UPos lmax() const;
|
||||
|
||||
/** @copydoc IndexInterface::id() */
|
||||
IndexId<0> id() const;
|
||||
|
||||
/** @copydoc IndexInterface::operator*() */
|
||||
Vector<DType> operator*() const;
|
||||
|
||||
/** @copydoc IndexInterface::dim() */
|
||||
SizeT dim() const;
|
||||
|
||||
/** @copydoc IndexInterface::range() */
|
||||
Sptr<YRange> range() const;
|
||||
|
||||
/** @copydoc IndexInterface::stepSize() */
|
||||
UPos stepSize(const IndexId<0> id) const;
|
||||
|
||||
/** @copydoc IndexInterface::stringMeta() */
|
||||
String stringMeta() const;
|
||||
|
||||
/** @copydoc IndexInterface::meta() */
|
||||
Vector<DType> meta() const;
|
||||
|
||||
/** @copydoc IndexInterface::at() */
|
||||
YIndex& at(const Vector<DType>& meta);
|
||||
|
||||
DXpr<None> ifor(const DXpr<None>& xpr, NoF&& f) const;
|
||||
|
||||
YIndex& operator()(const Sptr<YIndex>& i);
|
||||
YIndex& operator()();
|
||||
|
||||
const DPack& pack() const;
|
||||
/** @copydoc IndexInterface::prange() */
|
||||
RangePtr prange(const YIndex& last) const;
|
||||
|
||||
/** @copydoc IndexInterface::deepFormat() */
|
||||
Vector<SizeT> deepFormat() const;
|
||||
|
||||
/** @copydoc IndexInterface::deepMax() */
|
||||
Vector<SizeT> deepMax() const;
|
||||
const YFormat& format() const;
|
||||
const YFormat& lexFormat() const;
|
||||
YIndex& setFormat(const YFormat& bs);
|
||||
|
||||
/** @copydoc IndexInterface::reformat() */
|
||||
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() */
|
||||
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:
|
||||
inline Vector<SizeT> mkFormat() const;
|
||||
inline Vector<SizeT> mkLexFormat() const;
|
||||
|
@ -107,26 +214,80 @@ namespace CNORXZ
|
|||
UPos mLMax = 0;
|
||||
};
|
||||
|
||||
/** ****
|
||||
Specialization: YIndex is a multi-index.
|
||||
@see index_is_multi
|
||||
*/
|
||||
template <>
|
||||
struct index_is_multi<YIndex>
|
||||
{ static constexpr bool value = true; };
|
||||
|
||||
/** ****
|
||||
Specialization: YIndex has sub-indices.
|
||||
@see has_sub
|
||||
*/
|
||||
template <>
|
||||
struct has_sub<YIndex>
|
||||
{ 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);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** ****
|
||||
Specific factory for YRange.
|
||||
*/
|
||||
class YRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
public:
|
||||
|
||||
/** Construct and setup factory.
|
||||
@param rvec Vector of ranges i.e. the sub-ranges the YRange consists of
|
||||
*/
|
||||
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);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** 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);
|
||||
|
||||
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>
|
||||
{
|
||||
public:
|
||||
|
@ -169,8 +337,16 @@ namespace CNORXZ
|
|||
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);
|
||||
|
||||
/** ****
|
||||
Specialize RangeCast for casts to YRange.
|
||||
@see RangeCast
|
||||
*/
|
||||
template <>
|
||||
struct RangeCast<YRange>
|
||||
{
|
||||
|
|
|
@ -334,12 +334,13 @@ namespace CNORXZ
|
|||
|
||||
YIndex& YIndex::at(const Vector<DType>& meta)
|
||||
{
|
||||
assert(meta.size() == mIs.size());
|
||||
IB::mPos = 0;
|
||||
CXZ_ASSERT(meta.size() == mIs.size(), "input meta size ("
|
||||
<< meta.size() << ") different from expected size ("
|
||||
<< mIs.size() << ")");
|
||||
for(SizeT i = 0; i != mIs.size(); ++i){
|
||||
mIs[i]->at(meta[i]);
|
||||
IB::mPos += mIs[i]->pos() * mFormat[i].val();
|
||||
}
|
||||
mkPos();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -415,9 +416,15 @@ namespace CNORXZ
|
|||
|
||||
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
|
||||
// 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 j0 = 0;
|
||||
SizeT xi = 1;
|
||||
|
@ -427,9 +434,7 @@ namespace CNORXZ
|
|||
xi *= mIs[i]->lmax().val();
|
||||
SizeT xj = s[j];
|
||||
if(xi < xj) {
|
||||
// TODO: IMPLEMENT!!!
|
||||
// check trivial format in this partition
|
||||
CXZ_ERROR("reformating with lower-dimensional formats has not yet been implemented");
|
||||
CXZ_ERROR("reformating with lower-dimensional formats is not possible; use sub-indices instead");
|
||||
continue;
|
||||
}
|
||||
j0 = j;
|
||||
|
@ -489,6 +494,19 @@ namespace CNORXZ
|
|||
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 *
|
||||
****************************/
|
||||
|
|
|
@ -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_group.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_file.h"
|
||||
#include "h5_group.h"
|
||||
#include "h5_table.h"
|
||||
#include "h5_dataset.h"
|
||||
#include "h5_type_id.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__
|
||||
#define __cxz_h5_content_base_h__
|
||||
|
@ -10,42 +20,129 @@ namespace CNORXZ
|
|||
{
|
||||
namespace hdf5
|
||||
{
|
||||
// TODO: IO save error handling !!!
|
||||
|
||||
/** *****
|
||||
Enum indicating the content type.
|
||||
Used by ContainerBase derivates to indicate the derived type.
|
||||
*/
|
||||
enum class ContentType {
|
||||
ATTR = 1,
|
||||
FILE = 2,
|
||||
GROUP = 3,
|
||||
DSET = 4,
|
||||
TABLE = 5,
|
||||
VALUE = 6,
|
||||
NONE = 0,
|
||||
FILE = 1,
|
||||
GROUP = 2,
|
||||
DSET = 3,
|
||||
TABLE = 4,
|
||||
};
|
||||
|
||||
/** ****
|
||||
Abstract base class for handling hdf5 objects.
|
||||
*/
|
||||
class ContentBase
|
||||
{
|
||||
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);
|
||||
|
||||
/** Virtual default destructor. */
|
||||
virtual ~ContentBase() = default;
|
||||
|
||||
/** Get the content type.
|
||||
@return Content type.
|
||||
*/
|
||||
virtual ContentType type() const = 0;
|
||||
|
||||
/** Check if in read-only mode
|
||||
@return True if read-only else false.
|
||||
*/
|
||||
virtual bool ro() const = 0;
|
||||
|
||||
/** Open object.
|
||||
@return Reference to this object.
|
||||
*/
|
||||
virtual ContentBase& open() = 0;
|
||||
|
||||
/** Close object.
|
||||
@return Reference to this object.
|
||||
*/
|
||||
virtual ContentBase& close() = 0;
|
||||
|
||||
/** Get object path.
|
||||
@return Absolute hdf5 file internal path of this object.
|
||||
*/
|
||||
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;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** Get parent object.
|
||||
@return Pointer to the parent of this object.
|
||||
*/
|
||||
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;
|
||||
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:
|
||||
String mName;
|
||||
const ContentBase* mParent = nullptr;
|
||||
RangePtr mRange;
|
||||
hid_t mId = 0;
|
||||
String mName; /**< Name of this object. */
|
||||
const ContentBase* mParent = nullptr; /**< Pointer to this object's parent. */
|
||||
hid_t mId = 0; /**< hdf5 identifier of the hdf5 object handled by this object. */
|
||||
};
|
||||
|
||||
/** Shortcut for a shared pointer to an abstract content object. */
|
||||
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__
|
||||
#define __cxz_h5_file_h__
|
||||
|
@ -10,14 +20,23 @@ namespace CNORXZ
|
|||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
|
||||
/** Destructor. Release all involved hdf5 ids. */
|
||||
~File();
|
||||
|
||||
virtual ContentType type() const override final;
|
||||
|
@ -26,8 +45,12 @@ namespace CNORXZ
|
|||
virtual File& close() override final;
|
||||
virtual String path() 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:
|
||||
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__
|
||||
#define __cxz_h5_group_cc_h__
|
||||
|
||||
#include "h5_group.h"
|
||||
#include "xpr/for.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
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>
|
||||
Sptr<STable<Ts...>> Group::getTable(const String& name, Tuple<Ts...> proto)
|
||||
{
|
||||
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 );
|
||||
if(tab == nullptr){
|
||||
auto stab = std::dynamic_pointer_cast<STable<Ts...>>(*i);
|
||||
|
@ -19,33 +52,54 @@ namespace CNORXZ
|
|||
return stab;
|
||||
}
|
||||
else {
|
||||
const RangePtr fields = tab->fields();
|
||||
(*i)->close();
|
||||
*i = std::make_shared<STable<Ts...>>(name, this, fields);
|
||||
return *i;
|
||||
auto stab = std::make_shared<STable<Ts...>>(name, this);
|
||||
*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>
|
||||
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_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;
|
||||
}
|
||||
|
||||
template <typename... Ts>
|
||||
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");
|
||||
Vector<String> nvec({name});
|
||||
Vector<DType> dvec({DType(name)});
|
||||
auto extr = URangeFactory<String>( nvec ).create();
|
||||
mCont.extend(extr);
|
||||
auto ii = mCont.begin();
|
||||
ii.at(dvec); // 'at' returns YIndex&, so cannot use it inline...
|
||||
mCont.extend( URangeFactory<String>( nvec ).create() );
|
||||
auto ii = getIndexTo(name);
|
||||
auto tab = std::make_shared<STable<Ts...>>(name, this, fnames);
|
||||
for(auto& d: data){
|
||||
tab->appendRecord(d);
|
||||
|
@ -54,6 +108,41 @@ namespace CNORXZ
|
|||
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__
|
||||
#define __cxz_h5_group_h__
|
||||
|
@ -9,11 +19,21 @@ namespace CNORXZ
|
|||
{
|
||||
namespace hdf5
|
||||
{
|
||||
/** ****
|
||||
Class to handle hdf5 groups.
|
||||
*/
|
||||
class Group : public ContentBase
|
||||
{
|
||||
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);
|
||||
|
||||
/** Destructor. Release all involved hdf5 ids. */
|
||||
~Group();
|
||||
|
||||
virtual ContentType type() const override;
|
||||
|
@ -22,31 +42,138 @@ namespace CNORXZ
|
|||
virtual Group& close() override;
|
||||
virtual String path() 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;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** 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>
|
||||
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;
|
||||
|
||||
/** Add a new group to this group.
|
||||
@param name Name of the created group.
|
||||
*/
|
||||
Group& addGroup(const String& name);
|
||||
|
||||
template <typename T>
|
||||
Group& addData(const String& name, const ArrayBase<T>& data);
|
||||
|
||||
/** Add a new table to this group.
|
||||
@tparam Ts Table element types.
|
||||
@param name Name of the created table.
|
||||
@param data Table data.
|
||||
@param fnames Table field names.
|
||||
*/
|
||||
template <typename... Ts>
|
||||
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:
|
||||
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();
|
||||
|
||||
/** Get index to requested group element (const).
|
||||
@param name Element name.
|
||||
*/
|
||||
AIndex<ContentPtr> getIndexTo(const String& name) const;
|
||||
|
||||
/** Get index to requested group element.
|
||||
@param name Element 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__
|
||||
#define __cxz_h5_table_cc_h__
|
||||
|
@ -9,6 +19,16 @@ namespace CNORXZ
|
|||
{
|
||||
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 <class F>
|
||||
decltype(auto) STable<Ts...>::iterRecords(F&& f) const
|
||||
|
@ -18,51 +38,69 @@ namespace CNORXZ
|
|||
}
|
||||
|
||||
template <typename... Ts>
|
||||
STable<Ts...>::STable(const String& name, const ContentBase* _parent,
|
||||
const Vector<String>& fnames) :
|
||||
STable<Ts...>::STable(const String& name, const ContentBase* _parent) :
|
||||
Table(name, _parent)
|
||||
{
|
||||
constexpr SizeT N = sizeof...(Ts);
|
||||
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));
|
||||
if(mFields != nullptr){
|
||||
|
||||
Tuple<Ts...> x;
|
||||
if(mRecords == nullptr) {
|
||||
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(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 {
|
||||
CXZ_ASSERT(mFields->size() == N, "expected tuple of size = " << mFields->size()
|
||||
<< ", got: " << N);
|
||||
Tuple<Ts...> x;
|
||||
iter<0,N>( [&](auto i) { CXZ_ASSERT
|
||||
( getTupleOffset(x, i) == mOffsets.data()[i],
|
||||
"wrong offset for field " << i << ": " << getTupleOffset(x, i)
|
||||
<< " vs " << mOffsets.data()[i] ); }, NoF{} );
|
||||
iter<0,N>( [&](auto i) { CXZ_ASSERT
|
||||
( sizeof(std::get<i>(x)) == mSizes.data()[i],
|
||||
"wrong size for field " << i << ": " << sizeof(std::get<i>(x))
|
||||
( sizeof(tget<i>(x)) == mSizes.data()[i],
|
||||
"wrong size for field " << i << ": " << sizeof(tget<i>(x))
|
||||
<< " vs " << mSizes.data()[i] ); }, NoF{} );
|
||||
iter<0,N>( [&](auto i) { CXZ_ASSERT
|
||||
( getTypeId(std::get<i>(x)) == mTypes.data()[i],
|
||||
"wrong type for field " << i << ": " << getTypeId(std::get<i>(x))
|
||||
( H5Tget_class(getTypeId(tget<i>(x))) == mTypes.data()[i],
|
||||
"wrong type for field " << i
|
||||
<< ": " << H5Tget_class(getTypeId(tget<i>(x)))
|
||||
<< " 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>
|
||||
STable<Ts...>& STable<Ts...>::appendRecord(const Tuple<Ts...>& t)
|
||||
{
|
||||
|
@ -71,10 +109,20 @@ namespace CNORXZ
|
|||
initTable(1, &t, sizeof(t), sizeof(t));
|
||||
}
|
||||
else {
|
||||
Table::appendRecord(1, &t, sizeof(t));
|
||||
Table::appendRecords(1, &t);
|
||||
}
|
||||
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__
|
||||
#define __cxz_h5_table_h__
|
||||
|
@ -9,13 +19,23 @@ namespace CNORXZ
|
|||
{
|
||||
namespace hdf5
|
||||
{
|
||||
/** ****
|
||||
Class to handle hdf5 tables.
|
||||
*/
|
||||
class Table : public ContentBase
|
||||
{
|
||||
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);
|
||||
|
||||
/** Destructor. Release all involved hdf5 ids. */
|
||||
~Table();
|
||||
|
||||
virtual ContentType type() const override final;
|
||||
|
@ -24,36 +44,130 @@ namespace CNORXZ
|
|||
virtual Table& close() override final;
|
||||
virtual String path() 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);
|
||||
|
||||
/** 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& 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;
|
||||
|
||||
/** Get records range.
|
||||
@return Pointer to the range.
|
||||
*/
|
||||
const RangePtr& records() const;
|
||||
|
||||
protected:
|
||||
RangePtr mRecords;
|
||||
RangePtr mFields; // -> FIndex (position -> offset)
|
||||
MArray<SizeT> mSizes;
|
||||
MArray<SizeT> mOffsets;
|
||||
MArray<hid_t> mTypes;
|
||||
hid_t mType = 0;
|
||||
RangePtr mRecords; /**< Records range. */
|
||||
RangePtr mFields; /**< Fields range. */ // -> FIndex (position -> offset)
|
||||
MArray<SizeT> mSizes; /**< Field element type sizes. */
|
||||
MArray<SizeT> mOffsets; /**< Field element offsets. */
|
||||
MArray<hid_t> mTypes; /**< Field element type ids. */
|
||||
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>
|
||||
class STable : public Table
|
||||
{
|
||||
public:
|
||||
DEFAULT_MEMBERS(STable);
|
||||
STable(const String& name, const ContentBase* _parent, const Vector<String>& fnames);
|
||||
DEFAULT_MEMBERS(STable); /**< Default constructors and assignments. */
|
||||
|
||||
/** 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);
|
||||
|
||||
/** Append records to the table.
|
||||
@param t Array of tuples containing the records.
|
||||
*/
|
||||
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>
|
||||
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__
|
||||
#define __cxz_h5_type_id_cc_h__
|
||||
|
@ -8,17 +18,9 @@ namespace CNORXZ
|
|||
{
|
||||
namespace hdf5
|
||||
{
|
||||
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>(&std::get<i>(t));
|
||||
return pos - beg;
|
||||
}
|
||||
|
||||
/**************
|
||||
* TypeId *
|
||||
**************/
|
||||
/*============+
|
||||
| TypeId |
|
||||
+============*/
|
||||
|
||||
template <typename T>
|
||||
inline hid_t TypeId<T>::get()
|
||||
|
@ -28,17 +30,17 @@ namespace CNORXZ
|
|||
|
||||
inline hid_t TypeId<SizeT>::get()
|
||||
{
|
||||
return H5T_NATIVE_ULONG;
|
||||
return H5Tcopy( H5T_NATIVE_ULONG );
|
||||
}
|
||||
|
||||
inline hid_t TypeId<Int>::get()
|
||||
{
|
||||
return H5T_NATIVE_INT;
|
||||
return H5Tcopy( H5T_NATIVE_INT );
|
||||
}
|
||||
|
||||
inline hid_t TypeId<Double>::get()
|
||||
{
|
||||
return H5T_NATIVE_DOUBLE;
|
||||
return H5Tcopy( H5T_NATIVE_DOUBLE );
|
||||
}
|
||||
|
||||
template <typename T, SizeT N>
|
||||
|
@ -48,9 +50,9 @@ namespace CNORXZ
|
|||
return arrtype;
|
||||
}
|
||||
|
||||
/*****************
|
||||
* getTypeId *
|
||||
*****************/
|
||||
/*===============+
|
||||
| getTypeId |
|
||||
+===============*/
|
||||
|
||||
template <typename T>
|
||||
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__
|
||||
#define __cxz_h5_type_id_h__
|
||||
|
||||
#include "base/types.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
namespace hdf5
|
||||
{
|
||||
template <SizeT N, typename... Ts>
|
||||
SizeT getTupleOffset(const Tuple<Ts...>& t, CSizeT<N> i);
|
||||
|
||||
/**************
|
||||
* TypeId *
|
||||
**************/
|
||||
|
||||
/** ****
|
||||
Get a valid hdf5 id for a given type.
|
||||
Return 0 if not implemented.
|
||||
@tparam T The type.
|
||||
*/
|
||||
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 <>
|
||||
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 <>
|
||||
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 <>
|
||||
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>
|
||||
struct TypeId<Arr<T,N>> { static inline hid_t get(); };
|
||||
|
||||
/*****************
|
||||
* getTypeId *
|
||||
*****************/
|
||||
struct TypeId<Arr<T,N>>
|
||||
{
|
||||
/** Get the type id for the given array. */
|
||||
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>
|
||||
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__
|
||||
#define __h5_types_h__
|
||||
|
@ -22,6 +34,13 @@ namespace CNORXZ
|
|||
template <typename... Ts>
|
||||
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_group.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/h5_table.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/h5_dataset.cc
|
||||
)
|
||||
|
||||
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"
|
||||
|
||||
|
@ -19,14 +31,121 @@ namespace CNORXZ
|
|||
return mParent;
|
||||
}
|
||||
|
||||
RangePtr ContentBase::range() const
|
||||
{
|
||||
return mRange;
|
||||
}
|
||||
|
||||
hid_t ContentBase::id() const
|
||||
{
|
||||
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()
|
||||
{
|
||||
if(isOpen()){
|
||||
return *this;
|
||||
}
|
||||
Int ex = this->exists();
|
||||
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){
|
||||
CXZ_ASSERT( ex == 1, "could not open file as read-only: '"
|
||||
<< fn << "' does not exist'");
|
||||
|
@ -67,7 +70,7 @@ namespace CNORXZ
|
|||
|
||||
String File::path() const
|
||||
{
|
||||
return String("/");
|
||||
return "";
|
||||
}
|
||||
|
||||
String File::filename() const
|
||||
|
@ -75,21 +78,25 @@ namespace CNORXZ
|
|||
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);
|
||||
if(fs.good()){
|
||||
ex = 1; // file exists
|
||||
ex = true; // file exists
|
||||
}
|
||||
fs.close();
|
||||
if(ex != 0){
|
||||
if(H5Fis_hdf5(this->filename().c_str()) <= 0){
|
||||
ex = 2; // file not in h5 format
|
||||
}
|
||||
}
|
||||
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_table.h"
|
||||
#include "h5_dataset.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
@ -30,14 +31,16 @@ namespace CNORXZ
|
|||
|
||||
Group& Group::open()
|
||||
{
|
||||
if(this->exists()){
|
||||
mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT );
|
||||
if(not isOpen()){
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -66,14 +69,23 @@ namespace CNORXZ
|
|||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -85,6 +97,22 @@ namespace CNORXZ
|
|||
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
|
||||
{
|
||||
CXZ_ASSERT(this->isOpen(), "tried to get content of closed group");
|
||||
|
@ -118,10 +146,12 @@ namespace CNORXZ
|
|||
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")){
|
||||
return false;
|
||||
H5Dclose(id);
|
||||
}
|
||||
hid_t attrid = H5Aopen(id, "CLASS", H5P_DEFAULT);
|
||||
const hid_t atype = H5Aget_type(attrid);
|
||||
|
@ -130,6 +160,7 @@ namespace CNORXZ
|
|||
const herr_t ret = H5Aread(attrid, atype, buff.data());
|
||||
H5Tclose(atype);
|
||||
H5Aclose(attrid);
|
||||
H5Dclose(id);
|
||||
if(ret != 0){
|
||||
return false;
|
||||
}
|
||||
|
@ -149,9 +180,9 @@ namespace CNORXZ
|
|||
index();
|
||||
H5O_info_t oinfo;
|
||||
#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
|
||||
H5Oget_info(id, &oinfo);
|
||||
H5Oget_info_by_name(id, name, &oinfo, H5P_DEFAULT);
|
||||
#endif
|
||||
switch (oinfo.type) {
|
||||
case H5O_TYPE_GROUP: {
|
||||
|
@ -159,12 +190,11 @@ namespace CNORXZ
|
|||
break;
|
||||
}
|
||||
case H5O_TYPE_DATASET: {
|
||||
if(isTable(id)){
|
||||
if(isTable(id, name)){
|
||||
*index = std::make_shared<Table>(sname, icd->parent);
|
||||
}
|
||||
else {
|
||||
CXZ_ERROR("IMPLEMENT!!!");
|
||||
//*index = std::make_shared<DSet>(sname, icd->parent);
|
||||
*index = std::make_shared<Dataset>(sname, icd->parent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -9,17 +9,20 @@ namespace CNORXZ
|
|||
Table::Table(const String& name, const ContentBase* _parent) :
|
||||
ContentBase(name, _parent)
|
||||
{
|
||||
if(H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT)){
|
||||
if(exists()){
|
||||
hsize_t nfields = 0;
|
||||
hsize_t nrecords = 0;
|
||||
H5TBget_table_info(mParent->id(), mName.c_str(), &nfields, &nrecords);
|
||||
mRecords = CRangeFactory( nrecords ).create();
|
||||
Vector<Arr<char,256>> fieldnames(nfields);
|
||||
Vector<char*> fieldsptr(nfields);
|
||||
for(SizeT i = 0; i != nfields; ++i){
|
||||
fieldsptr[i] = fieldnames[i].data();
|
||||
}
|
||||
Vector<SizeT> offsets(nfields);
|
||||
Vector<SizeT> sizes(nfields);
|
||||
SizeT typesize = 0;
|
||||
H5TBget_field_info(mParent->id(), mName.c_str(), fieldsptr.data(), sizes.data(),
|
||||
offsets.data(), &typesize);
|
||||
offsets.data(), &mTypesize);
|
||||
Vector<FieldID> fields(nfields);
|
||||
for(SizeT i = 0; i != nfields; ++i){
|
||||
fields[i].first = i;
|
||||
|
@ -62,6 +65,7 @@ namespace CNORXZ
|
|||
if(mId == 0){
|
||||
mId = H5Dopen(mParent->id(), mName.c_str(), H5P_DEFAULT);
|
||||
mType = H5Dget_type(mId);
|
||||
mkTypes();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -71,6 +75,7 @@ namespace CNORXZ
|
|||
if(mId != 0){
|
||||
H5Tclose(mType);
|
||||
H5Dclose(mId);
|
||||
mId = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -85,6 +90,11 @@ namespace CNORXZ
|
|||
return mParent->filename();
|
||||
}
|
||||
|
||||
bool Table::exists() const
|
||||
{
|
||||
return H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT) > 0;
|
||||
}
|
||||
|
||||
Table& Table::initFieldNames(const Vector<String>& fnames)
|
||||
{
|
||||
CXZ_ASSERT(mFields == nullptr, "fields already initialized");
|
||||
|
@ -106,28 +116,61 @@ namespace CNORXZ
|
|||
for(auto fi = fr->begin(); fi != fr->end(); ++fi){
|
||||
fields[fi.lex()] = (*fi).second.c_str();
|
||||
}
|
||||
mTypesize = dsize;
|
||||
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);
|
||||
CXZ_ASSERT(err >= 0, "error while initialzing table: error code = " << err);
|
||||
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() );
|
||||
const herr_t err = H5TBappend_records(mParent->id(), mName.c_str(), n, dsize,
|
||||
mRecords = mRecords->extend( CRangeFactory(n).create() );
|
||||
const herr_t err = H5TBappend_records(mParent->id(), mName.c_str(), n, mTypesize,
|
||||
mOffsets.data(), mSizes.data(), data);
|
||||
CXZ_ASSERT(err >= 0, "error while appending record to table: error code = " << err);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
return mFields;
|
||||
|
@ -138,5 +181,64 @@ namespace CNORXZ
|
|||
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_dependencies(h5basic cnorxz cnorxzhdf5)
|
||||
target_link_libraries(h5basic ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${HDF5_LIBS} cnorxz cnorxzhdf5)
|
||||
add_dependencies(h5basic cnorxz cnorxzhdf5 test_lib)
|
||||
target_link_libraries(h5basic ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${HDF5_LIBS} cnorxz cnorxzhdf5 test_lib)
|
||||
add_test(NAME h5basic COMMAND h5basic)
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
#include "gtest/gtest.h"
|
||||
|
||||
#include "cnorxz_hdf5.h"
|
||||
#include "test_numbers.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace CNORXZ;
|
||||
using namespace CNORXZ::hdf5;
|
||||
using Test::Numbers;
|
||||
|
||||
static const String testh5file = "test_file.h5";
|
||||
|
||||
|
@ -39,24 +41,43 @@ namespace
|
|||
Group_Test()
|
||||
{
|
||||
mFileName = testh5file;
|
||||
mGrps = { "gr1", "gr2" };
|
||||
mFs = {"field1","second","real"};
|
||||
Vector<Tuple<SizeT,Int,Double>> v
|
||||
( { {0, -6, 3.141},
|
||||
{3, -8, 0.789},
|
||||
{34, 4, 10.009},
|
||||
{2, -777, -9.77},
|
||||
{321, 0, -0.003}
|
||||
// Tuple has reverse (!) memory ordering:
|
||||
Vector<Tuple<Double,Int,SizeT>> v
|
||||
( { { 3.141, -6, 0 },
|
||||
{ 0.789, -8, 3 },
|
||||
{ 10.009, 4, 34 },
|
||||
{ -9.77, -777, 2 },
|
||||
{ -0.003, 0, 321 }
|
||||
} );
|
||||
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;
|
||||
Vector<String> mGrps;
|
||||
|
||||
Vector<String> mFs;
|
||||
MArray<Tuple<SizeT,Int,Double>> mTabA;
|
||||
Arr<String,3> mFs;
|
||||
MArray<Tuple<Double,Int,SizeT>> mTabA;
|
||||
MArray<DType> mTabD;
|
||||
MArray<Double> mData;
|
||||
};
|
||||
|
||||
|
||||
|
@ -80,9 +101,28 @@ namespace
|
|||
File h5f(mFileName, false);
|
||||
EXPECT_FALSE(h5f.ro());
|
||||
h5f.open();
|
||||
h5f.addAttribute("fprop", static_cast<Double>(3.141));
|
||||
h5f.addGroup("gr1");
|
||||
h5f.getGroup("gr1")->addAttribute("att1", String("text"));
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -91,7 +131,15 @@ namespace
|
|||
File h5f(mFileName, false);
|
||||
h5f.open();
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -100,7 +148,146 @@ namespace
|
|||
File h5f(mFileName, true);
|
||||
h5f.open();
|
||||
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);
|
||||
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(mi2.lmax().val(), mRange2->size());
|
||||
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() } ) );
|
||||
VCHECK(toString(yi.deepFormat()));
|
||||
|
||||
mi.reformat( yi.deepFormat(), yi.deepMax() );
|
||||
VCHECK(toString(mi.deepFormat()));
|
||||
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