Compare commits
No commits in common. "main" and "multi-array" have entirely different histories.
main
...
multi-arra
264 changed files with 20622 additions and 34853 deletions
36
.github/workflows/main.yml
vendored
36
.github/workflows/main.yml
vendored
|
@ -1,36 +0,0 @@
|
|||
# This file is based on https://github.com/satu0king/Github-Documentation-With-Doxygen/blob/master/main.yml
|
||||
|
||||
name: Doxygen Action
|
||||
|
||||
# Trigger workflow only on pushed to master branch:
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Doxygen Action
|
||||
uses: mattnotmitt/doxygen-action@v1.1.0
|
||||
with:
|
||||
# Path to Doxyfile
|
||||
doxyfile-path: "./Doxyfile"
|
||||
# Working directory
|
||||
working-directory: "./doc/doxy"
|
||||
|
||||
- name: Deploy
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./doc/doxy/html
|
||||
|
||||
permissions:
|
||||
contents: write
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -4,6 +4,4 @@ build/
|
|||
install/
|
||||
*/build/
|
||||
*/install/
|
||||
src/lib/hl_ops/*.cc
|
||||
doc/doxy/html/
|
||||
doc/doxy/latex/
|
||||
src/lib/hl_ops/*.cc
|
17
.gitlab-ci.yml
Normal file
17
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
before_script:
|
||||
- export GTEST_ROOT=/opt/gtest-1.8.0
|
||||
|
||||
image: docker.io/rqcd/centos-buildtools:7.2.1511
|
||||
|
||||
stages:
|
||||
- build
|
||||
|
||||
build-centos:
|
||||
stage: build
|
||||
script:
|
||||
- source /opt/rh/devtoolset-7/enable
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake3 ..
|
||||
- make -j2
|
||||
- make test
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
|
||||
steps:
|
||||
build:
|
||||
image: chizeta/centos:8
|
||||
commands:
|
||||
- source /opt/rh/gcc-toolset-9/enable
|
||||
- mkdir build-gcc
|
||||
- cd build-gcc
|
||||
- cmake3 -DSCALAR_BUILD=on ..
|
||||
- make -j2
|
||||
- make test
|
||||
- cd ..
|
||||
- mkdir build-clang
|
||||
- cd build-clang
|
||||
- CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake3 -DRUN_PIPELINE=on -DSCALAR_BUILD=on ..
|
||||
- make -j2
|
||||
- make test
|
105
CMakeLists.txt
105
CMakeLists.txt
|
@ -1,38 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(cnorxz)
|
||||
|
||||
# LIB VERSION
|
||||
|
||||
set(V_MAJOR 0)
|
||||
set(V_MINOR 0)
|
||||
set(V_PATCH 0)
|
||||
set(VERSION "${V_MAJOR}.${V_MINOR}.${V_PATCH}")
|
||||
|
||||
# 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 rev-parse --abbrev-ref HEAD" OUTPUT_VARIABLE GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# BUILD VERSION STRING
|
||||
|
||||
message(STATUS "git hash = ${GIT_HASH}")
|
||||
message(STATUS "git branch = ${GIT_BRANCH}")
|
||||
if(NOT ("${GIT_BRANCH}" EQUAL "release"))
|
||||
string(SUBSTRING ${GIT_HASH} 0 7 GIT_HASH_SHORT)
|
||||
set(VERSION "${VERSION}-${GIT_BRANCH}-${GIT_HASH_SHORT}")
|
||||
endif()
|
||||
message(STATUS "version = ${VERSION}")
|
||||
|
||||
# CHECK COMPILER
|
||||
project(multi_array)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0)
|
||||
|
@ -42,41 +10,20 @@ 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
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++14 -Wpedantic -Ofast -march=native -faligned-new -funroll-loops -fopenmp")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++14 -g -Wpedantic -Ofast -march=native -faligned-new -funroll-loops -fopenmp -ftemplate-backtrace-limit=0")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++14 -g -Wpedantic -O0 -march=native -faligned-new -funroll-loops -fopenmp")
|
||||
|
||||
enable_testing()
|
||||
|
||||
# INSTALL PATH
|
||||
|
||||
if(IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}")
|
||||
set(INSTALL_PATH ${CMAKE_INSTALL_PREFIX})
|
||||
else()
|
||||
#set(INSTALL_PATH ${CMAKE_SOURCE_DIR}/install)
|
||||
get_filename_component(INSTALL_PATH ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_PREFIX} ABSOLUTE)
|
||||
endif()
|
||||
message(STATUS "found absolute install path '${INSTALL_PATH}'")
|
||||
message(WARNING "found absolute install path '${INSTALL_PATH}'")
|
||||
|
||||
# SCALAR / INTRINSICS
|
||||
|
||||
if(NOT ${SCALAR_BUILD})
|
||||
message(STATUS "check for intrinsics")
|
||||
check_avx()
|
||||
if(AVX_AVAIL)
|
||||
message(STATUS "AVX available")
|
||||
add_definitions("-DCXZ_HAVE_AVX")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
|
||||
else()
|
||||
message(STATUS "AVX not available")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# CHECK LIBRARIES : GTest
|
||||
|
||||
message(STATUS "check for libraries")
|
||||
find_package( GTest REQUIRED )
|
||||
if(GTest_FOUND)
|
||||
include_directories(${GTEST_INCLUDE_DIRS})
|
||||
|
@ -84,8 +31,6 @@ else()
|
|||
message(FATAL_ERROR "GTest not found")
|
||||
endif()
|
||||
|
||||
# CHECK LIBRARIES : Threads
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
if(Threads_FOUND)
|
||||
#include_directories(${Threads_INCLUDE_DIRS})
|
||||
|
@ -93,42 +38,4 @@ 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()
|
||||
set(ENABLE_cereal TRUE CACHE BOOL "enable hdf5")
|
||||
endif()
|
||||
|
||||
find_package(cereal QUIET)
|
||||
if(cereal_FOUND)
|
||||
message(STATUS "found cereal")
|
||||
if(ENABLE_cereal)
|
||||
message(STATUS "enable cereal")
|
||||
add_definitions(-DHAVE_CEREAL)
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "no cereal")
|
||||
if(ENABLE_cereal)
|
||||
message(FATAL_ERROR "cereal has been enabled but the cereal library has not been found")
|
||||
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)
|
||||
|
|
21
LICENSE
21
LICENSE
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
200
README.md
200
README.md
|
@ -1,154 +1,120 @@
|
|||
# Container with Native Operation Routines and Expressions (CNORXZ)
|
||||
|
||||
(as always, the name was there before the acronym)
|
||||
|
||||
![Image](./cnorxz_logo.png)
|
||||
# Multi Array Container Library
|
||||
|
||||
## Description
|
||||
|
||||
This library provides a framework for handling multi dimensional data containers (arrays or array-like types), their meta data, and several kinds of operations on one or more of them.
|
||||
This library provides a framework for handling multi dimensional containers. This includes the basic container class template `MultiArrayBase` and their derivates, the Range class templates on which the containers are defined, as well as some operation class templates, which allow comfortable calling of operations on the containers.
|
||||
|
||||
## Build instructions
|
||||
|
||||
The library can be installed by the following procedure (`gtest` required):
|
||||
|
||||
```bash
|
||||
git clone git@git.f3l.de:chizeta/cnorxz.git <LIBRARY_ROOT_DIR>
|
||||
mkdir <BUILD_DIR>
|
||||
git clone git@rqcd.ur.de:czimmermann/multi_array.git <SOURCE_DIR>
|
||||
cd <BUILD_DIR>
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> <LIBRARY_ROOT_DIR>
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> <SOURCE_DIR>
|
||||
make install
|
||||
```
|
||||
|
||||
To build the doxygen:
|
||||
## Usage and Examples
|
||||
|
||||
```bash
|
||||
cd <SOURCE_DIR>/doc/doxy
|
||||
doxygen Doxyfile
|
||||
```
|
||||
To use the features of the libraries one has to include `multi_array_header.h` and link against the `libmultiarray.so`.
|
||||
The tools of the library are accessible within the namespace `MultiArrayTools`.
|
||||
|
||||
## Linking
|
||||
### Some Terms
|
||||
|
||||
To use the features of the libraries one has to include `cnorxz.h` and link against the `libcnorxz.so`.
|
||||
The tools of the library are accessible within the namespace `CNORXZ`.
|
||||
* Ranges: A set of meta data which is mapped onto the linear position. Every container is supposed to be defined on at least one Range. In the simplest case a Range space "containes" the numbers [0,...,rangesize]. Ranges have to be created via the corresponding factory and only exist within a shared pointer. They cannot be copied. The reason is, that every operation performed on the containers, has to identify common sets of ranges, on which the containers are defined. Every range inherits the `RangeBase` class.
|
||||
|
||||
## Documentation
|
||||
* Indices: They can be thought of as iterators of the range space. In the special case of the `ContainerIndex` it is also an iterator over the corresponding container. The index type must be known at compile time (static polymorphism). Indices on a range can be obtained by `getIndex( range )`. For Container Indices call the `begin()` function of a `MultiArray`. Indices are crucial for defining operations.
|
||||
|
||||
(Also consider doxygen)
|
||||
* `MultiArray<T,Ranges...>`: Contains data of type `T` and is defined on `Ranges...`.
|
||||
* `[Const]Slice<T,Ranges...>`: Views data of type `T` and acts as a MultiArray defined on `Ranges...`.
|
||||
* `FunctionalMultiArray`: Additional template argument indicating the funtion. The value at some position is then defined by the function value obtained from the meta data of the indices/ranges.
|
||||
|
||||
### Basics and Library organization
|
||||
On each of these types one can perform an operation by calling `operator(...)` where within the braces the corresponding indices have to be specified (see example below).
|
||||
|
||||
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).
|
||||
### Example
|
||||
|
||||
#### Ranges {#sec-ranges}
|
||||
```c++
|
||||
|
||||
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:
|
||||
#include "multi_array_header.h"
|
||||
|
||||
* `CRange` : Classic one-dimensional range. The meta data space is simply given by integer numbers running from `0` to `size-1`. The range size is determined at runtime.
|
||||
namespace mat = MultiArrayTools;
|
||||
|
||||
* `URange<MetaT>` : Generic One-dimensional range. The meta data space is user defined, the meta data type is passed as template argument. The range size is determined at runtime.
|
||||
typedef mat::SingleRange<double,mat::SpaceType::ANY> DRange;
|
||||
typedef mat::SingleRangeFactory<double,mat::SpaceType::ANY> DRangeF;
|
||||
typedef mat::SingleRange<std::string,mat::SpaceType::ANY> SRange;
|
||||
typedef mat::SingleRangeFactory<std::string,mat::SpaceType::ANY> SRangeF;
|
||||
typedef mat::SingleRange<size_t,mat::SpaceType::NONE> CRange; // also provided as 'ClassicR'
|
||||
typedef mat::SingleRangeFactory<size_t,mat::SpaceType::NONE> CRangeF;
|
||||
|
||||
* `SRange<MetaT,S>` : The same as `URange`, but the range length is fixed at compile time by the template integer variable `S`.
|
||||
/*create ranges*/
|
||||
std::vector<double> meta1({...});
|
||||
std::vector<double> meta2({...});
|
||||
std::vector<std::string> meta3({...});
|
||||
|
||||
* `PRange<RangeT>` : Partial or sub-range, i.e. a user-defined subspace of another range. The type of the range must be known at compile time, the subspace can be specified at runtime.
|
||||
DRangeF drf1(meta1);
|
||||
DRangeF drf2(meta2);
|
||||
SRangeF srf(meta3);
|
||||
CRangeF crf(10); // specialized in this case; only size needed.
|
||||
|
||||
* `MRange<RangeTs...>` : Multi-dimensional range, spanned by a set of ranges. The number of ranges, as well as their types must be known at compile time.
|
||||
auto dr1 = mat::createExplicit( drf1 );
|
||||
auto dr2 = mat::createExplicit( drf2 );
|
||||
auto sr = mat::createExplicit( srf );
|
||||
auto cr = mat::createExplicit( crf );
|
||||
|
||||
* `YRange` : The same as `MRange` but the number of ranges and their types can be specified at runtime.
|
||||
mat::MultiArray<double,DRange,DRange,SRange,CRange> ma_a(dr1,dr2,sr,cr,0);
|
||||
mat::MultiArray<double,SRange,SRange> ma_b(sr,sr,0);
|
||||
|
||||
#### 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>`).
|
||||
|
||||
Apart from range specific indices, there exist also special indices:
|
||||
|
||||
* `DIndex` : Dynamic index wrapper, for the case that the index type cannot be determined at compile time.
|
||||
|
||||
* `AIndex<T>` : Array index. Const iterators pointing to the data of an array-type object with data type `T`.
|
||||
|
||||
* `BIndex<T>` : The same as `AIndex`, but not const.
|
||||
|
||||
#### Array types {#sec-array-types}
|
||||
|
||||
Arrays or array-like types contain or view datasets and are derived from `CArrayBase<T>` (const) or `ArrayBase<T>` for a given data type `T`. All array types 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`.
|
||||
|
||||
#### Expressions and Operations
|
||||
|
||||
In the context of this library, *expressions* are classes representing an expression that is supposed to be executed at given points during an iteration proceedure that involves one or more indexed quantities. Each expression type must fulfill the following requirements:
|
||||
|
||||
* There must be an implementation of `operator()` taking a multi-position argument indicating the position for the current iteration of each involved object according to its indices. The function can have an expression defined return value, which can be further processed.
|
||||
|
||||
* There must be an implementation of `rootSteps()` taking an index ID as argument. The function should return jump sizes for each involved object corresponding to the given index.
|
||||
|
||||
Each expression `Xpr` should be derived from the class `XprInterface<Xpr>`, where `Xpr` is a recurring template argument (static polymorphism).
|
||||
|
||||
There are two important expression types:
|
||||
|
||||
* *For* expressions: They represent a for loop over a given index.
|
||||
|
||||
* *Operations*: They correspond to one or more indexed array types and given operation on or between them. If an operation handles nothing but the access to one single array, it is called *Operation* *Root*.
|
||||
|
||||
Example:
|
||||
```cpp
|
||||
#include "cnroxz.h"
|
||||
|
||||
using namespace CNORZX;
|
||||
|
||||
RangePtr r = CRangeFactory(3).create(); // [0,1,2]
|
||||
RangePtr s = CRangeFactory(5).create(); // [0,1,2,3,4]
|
||||
RangePtr t = URangeFactory<Int>(Vector<Int>{4,5,6}).create(); // [4,5,6]
|
||||
i = std::make_shared<CIndex>(r);
|
||||
j = std::make_shared<CIndex>(s);
|
||||
k = std::make_shared<UIndex<Int>>(t);
|
||||
|
||||
MArray<Double> a(r*s*t); // 3-dim array, dimensions = [3,5,3], size = 45
|
||||
MArray<Double> b(r*t); // 2-dim array, dimensions = [3,3], size = 9
|
||||
MArray<Double> c(s*t); // 2-dim array, dimensions = [3,5], size = 15
|
||||
|
||||
// set array element values of a,b,c here...
|
||||
|
||||
c(j*k) += ( a(i*j*k) * b(j*k) * xpr(k) ).c(i);
|
||||
|
||||
/* Explanation of the above line:
|
||||
|
||||
c(j*k), a(i*j*k), b(j*k) and xpr(k) are operation roots, i.e.
|
||||
they manage access to the arrays c,a,b and the meta data space of index k
|
||||
|
||||
The operations between the operation roots are also operations in the
|
||||
sense of this nomenclature, i.e. a(i*j*k) * b(j*k) is again an operation.
|
||||
|
||||
The operation member function c() creates contraction, i.e. a for loop
|
||||
over the given index (i). If no further functions are specified, the values
|
||||
returned by the underlying operations are summed up for equivalent index
|
||||
combinations.
|
||||
|
||||
The += invokes a for loop over the indices on the l.h.s.. The values returned
|
||||
by the expression on the r.h.s. are added to the l.h.s. Something similar could be done
|
||||
with a = operator. Then the values would just be assigned instead of added.
|
||||
|
||||
*/
|
||||
|
||||
// Equivalent C-stype for loop (if a,b,c were C-style arrays):
|
||||
|
||||
for(size_t j = 0; j < s; ++j){
|
||||
for(size_t k = 0; k < t; ++k){
|
||||
int kv = k+4;
|
||||
double x = 0;
|
||||
// the contraction part:
|
||||
for(size_t i = 0; i < r; ++i){
|
||||
x += a[i*s*t+j*t+k] * b[j*t+k] * kv;
|
||||
}
|
||||
c[j*t+k] += x;
|
||||
}
|
||||
/* assign some values... */
|
||||
double val = 1.;
|
||||
for(auto& x: ma_a){
|
||||
x = val += 1;
|
||||
}
|
||||
|
||||
for(auto& x: ma_b){
|
||||
x = val /= 2.;
|
||||
}
|
||||
|
||||
mat::FunctionalMultiArray<double,plus<double>,DRange,DRange> fma(dr1,dr2);
|
||||
mat::MultiArray<double,DRange,DRange> res1(dr1,dr2);
|
||||
mat::MultiArray<double,DRange,DRange> res2(dr1,dr2);
|
||||
|
||||
/* get indices... */
|
||||
auto i1 = mat::getIndex( dr1 );
|
||||
auto i2 = mat::getIndex( dr2 );
|
||||
auto i3 = mat::getIndex( sr );
|
||||
auto i4 = mat::getIndex( sr );
|
||||
auto i5 = mat::getIndex( cr );
|
||||
|
||||
i3->at(<metaString>);
|
||||
i5->at(<metaNum>);
|
||||
|
||||
/* performs plus operation on each element in hypercube spanned by i1,i2,i4
|
||||
* and sums up resulting values by iterating over i4. i3 and i5 are fixed to the positions
|
||||
* given by the meta data above : */
|
||||
res1(i1,i2) += (ma_a(i1,i2,i4,i5) + ma_b(i4,i3)).c(i4);
|
||||
|
||||
/* calculates i2.meta() + i1.meta() and divide res1 at the corresponding entry by the result */
|
||||
res2(i1,i2) = res1(i1,i2) / fma(i2,i1)
|
||||
```
|
||||
|
||||
More documentation will follow...
|
||||
Further examples will follow; you can also look in the test executable source files in `./src/test/*.cc`
|
||||
|
||||
## Acknowledgments
|
||||
# Multithreading
|
||||
|
||||
GitHub Doxygen Task based on work by [satu0king](https://github.com/satu0king/Github-Documentation-With-Doxygen/tree/master).
|
||||
Multithreading can be enabled by the operation class member function `par()`, which will parallelize the top loop. E.g. for the operation in the example above:
|
||||
```c++
|
||||
/* Enable multithreading for the loop over i1 */
|
||||
res1(i1,i2).par() = (ma_a(i1,i2,i4,i5) + ma_b(i4,i3)).c(i4);
|
||||
```
|
||||
Caution: If you want to multithread operations over functional multi arrays, you have to make sure by yourself that involved functors are either static or const (const member variables).
|
||||
|
||||
I want to thank Gesina Schwalbe for creating the logo.
|
||||
# Planned features
|
||||
|
||||
Basically the structure of the operation routines allows in some cases (at least in those, where it is possible for simple c++ for loops) vectorization. So far the necessary implamentations are not done, but it is planned to enable these features.
|
||||
|
||||
# Known Issues
|
||||
|
||||
I didn't care that much about error handling because of missing time. There it might happen that you declare a `MultiArray` or `Slice` and an operation on it yields a segfault because it was forgotten to instancate the underlying container. Of course, there should be some mechanism, that catches such things, but due to the afore mentioned lack of time, it has not been implemented in every case. If you encounter such problems, pleas tell me, but be aware, that I won't fix it very soon.
|
||||
|
||||
There are unit tests, which cover the all crucial parts of this library, but probably not every special case. Hence, there is no warranty, that, if you do something fancy I didn't consider, everything works fine.
|
14
TODO
14
TODO
|
@ -1,14 +0,0 @@
|
|||
|
||||
include/operation/op_types.cc.h@225: "build and execute assign expression forwarding outer index"
|
||||
include/operation/op_types.cc.h@498: "implement ifor with func arg"
|
||||
opt/hdf5/include/h5_content_base.h@23: "IO save error handling"
|
||||
opt/hdf5/lib/h5_dataset.cc@124: "all sub-ranges explicity"
|
||||
lib/ranges/crange.cc@94: "preliminary solution (TODO: implement xpr that simply returns PosT value)"
|
||||
include/ranges/srange.cc.h@307: "check for selected static sizes of SRange -> return SRange"
|
||||
include/xpr/for.cc.h@324: "check for write access"
|
||||
include/base/dtype.cc.h@23: "for tuple use vector<DType>"
|
||||
include/ranges/urange.cc.h@384: "else general transform using DType (better than nothing), to be implemented"
|
||||
include/ranges/urange.cc.h@448: "else general transform using DType (better than nothing), to be implemented"
|
||||
include/array/array_base.cc.h@184: "check further compatibility of index/range format"
|
||||
include/array/array_base.cc.h@376: "check further compatibility of index/range format"
|
||||
include/ranges/index_base.cc.h@109: "if this assert never applies, remove mPtrId (-> Defaults)"
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
macro(check_avx)
|
||||
include(CheckCXXSourceCompiles)
|
||||
set(CMAKE_REQUIRED_FLAGS "-Wall -Werror -Wpedantic -std=c++17 -mavx")
|
||||
check_cxx_source_compiles("
|
||||
#include <immintrin.h>
|
||||
#include <iostream>
|
||||
int main()
|
||||
{
|
||||
const double a[4] = { 0,0,0,0 };
|
||||
const double b[4] = { 0,0,0,0 };
|
||||
double o[4] = { 0,0,0,0 };
|
||||
__m256d av = _mm256_load_pd(a);
|
||||
__m256d bv = _mm256_load_pd(b);
|
||||
__m256d ov = _mm256_add_pd(av, bv);
|
||||
_mm256_store_pd(o, ov);
|
||||
std::cout << o[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
AVX_AVAIL
|
||||
)
|
||||
endmacro()
|
||||
|
BIN
cnorxz_logo.png
BIN
cnorxz_logo.png
Binary file not shown.
Before Width: | Height: | Size: 44 KiB |
2774
doc/doxy/Doxyfile
2774
doc/doxy/Doxyfile
File diff suppressed because it is too large
Load diff
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB |
|
@ -1,36 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
|
||||
<meta name="generator" content="Doxygen 1.10.0"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>CNORXZ: Container with Native Operation Routines and Expressions (CNORXZ)</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<script type="text/javascript" src="clipboard.js"></script>
|
||||
<script type="text/javascript" src="cookie.js"></script>
|
||||
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="search/searchdata.js"></script>
|
||||
<script type="text/javascript" src="search/search.js"></script>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<link rel="icon" href="$relpath^cnorxz_logo_mini.png" type="image/x-icon" />
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr id="projectrow">
|
||||
<td id="projectlogo"><img alt="Logo" src="cnorxz_logo_mini.png"/></td>
|
||||
<td id="projectalign">
|
||||
<div id="projectname">CNORXZ
|
||||
</div>
|
||||
<div id="projectbrief">Container with Native Operation Routines and Expressions</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
|
@ -1 +0,0 @@
|
|||
../../../cnorxz_logo.png
|
|
@ -2,14 +2,5 @@
|
|||
include_directories(${CMAKE_SOURCE_DIR}/src/include)
|
||||
add_subdirectory(tests)
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(bin)
|
||||
|
||||
if(ENABLE_hdf5)
|
||||
add_subdirectory(opt/hdf5)
|
||||
endif()
|
||||
|
||||
if(ENABLE_cereal)
|
||||
add_subdirectory(opt/cereal)
|
||||
endif()
|
||||
|
||||
install(DIRECTORY include/ DESTINATION ${INSTALL_PATH}/include/cnorxz)
|
||||
install(DIRECTORY include/ DESTINATION ${INSTALL_PATH}/include)
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
add_executable(cnorxz-config config.cc)
|
||||
add_dependencies(cnorxz-config cnorxz)
|
||||
target_link_libraries(cnorxz-config cnorxz)
|
||||
|
||||
install(TARGETS cnorxz-config RUNTIME DESTINATION ${INSTALL_PATH}/bin)
|
|
@ -1,62 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file bin/config.cc
|
||||
@brief Program for printing cnorxz configurations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include "base/config.h"
|
||||
|
||||
using CNORXZ::String;
|
||||
using CNORXZ::SizeT;
|
||||
typedef std::map<String,std::function<String(void)>> CMapT;
|
||||
|
||||
auto configMap()
|
||||
{
|
||||
CMapT m;
|
||||
m["--version"] = CNORXZ::Config::version;
|
||||
m["--commit"] = CNORXZ::Config::commit;
|
||||
m["--flags"] = CNORXZ::Config::flags;
|
||||
return m;
|
||||
}
|
||||
|
||||
void printUsage(const String& prog, const CMapT& cm)
|
||||
{
|
||||
std::cout << "usage: " << prog << " ";
|
||||
for(const auto& x: cm){
|
||||
std::cout << "[" << x.first << "] ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const String prog(argv[0]);
|
||||
const auto cm = configMap();
|
||||
if(argc == 1){
|
||||
printUsage(prog, cm);
|
||||
}
|
||||
try {
|
||||
for(SizeT i = 1; i != static_cast<SizeT>(argc); ++i){
|
||||
std::cout << cm.at( String(argv[i]) )() << std::endl;
|
||||
}
|
||||
}
|
||||
catch(const std::out_of_range& e){
|
||||
std::cerr << "caught exception: " << e.what() << std::endl;
|
||||
printUsage(prog, cm);
|
||||
return 1;
|
||||
}
|
||||
catch(...){
|
||||
std::cerr << "caught generic exception" << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
89
src/include/allocator.h
Normal file
89
src/include/allocator.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
|
||||
#ifndef __ma_allocator__
|
||||
#define __ma_allocator__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#define MIB_SIZE 1024*1024 // 1MiB
|
||||
#define WARN_SIZE MIB_SIZE*100 // 100 MiB
|
||||
|
||||
namespace MultiArrayHelper
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct Allocator
|
||||
{
|
||||
typedef T value_type;
|
||||
static constexpr size_t type_size = sizeof(value_type);
|
||||
static constexpr size_t N = 32;
|
||||
|
||||
struct VX
|
||||
{
|
||||
alignas(N) char x[N];
|
||||
};
|
||||
|
||||
Allocator() = default;
|
||||
|
||||
template <typename U>
|
||||
Allocator(const Allocator<U>& x) {}
|
||||
|
||||
T* allocate(size_t n)
|
||||
{
|
||||
const size_t nn = n*type_size;
|
||||
if(nn >= WARN_SIZE){
|
||||
std::cout << __func__ << ": WARNING: allocating " << nn/(MIB_SIZE) << " MiB" << std::endl;
|
||||
}
|
||||
const size_t off = nn%N;
|
||||
const size_t nnx = (off == 0) ? nn : nn + N - off;
|
||||
const size_t nnd = nnx/N;
|
||||
VX* vx = new VX[nnd];
|
||||
return reinterpret_cast<T*>(vx);
|
||||
}
|
||||
|
||||
void deallocate(T* p, size_t n)
|
||||
{
|
||||
VX* vx = reinterpret_cast<VX*>(p);
|
||||
delete [] vx;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
bool operator==(const Allocator<T>& a, const Allocator<U>& b)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
bool operator!=(const Allocator<T>& a, const Allocator<U>& b)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace MultiArrayHelper
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
template <typename T>
|
||||
using vector = std::vector<T,MultiArrayHelper::Allocator<T>>;
|
||||
|
||||
template <typename T>
|
||||
inline std::vector<T> toStdVec(const vector<T>& v)
|
||||
{
|
||||
return std::vector<T>(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline vector<T> toMatVec(const std::vector<T>& v)
|
||||
{
|
||||
return vector<T>(v.begin(), v.end());
|
||||
}
|
||||
|
||||
} // namespace MultiArrayTools
|
||||
|
||||
#endif
|
299
src/include/arith.h
Normal file
299
src/include/arith.h
Normal file
|
@ -0,0 +1,299 @@
|
|||
|
||||
#ifndef __arith_h__
|
||||
#define __arith_h__
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <size_t N>
|
||||
struct ArgPack
|
||||
{
|
||||
template <class F, class Tuple, typename... As>
|
||||
static inline auto mk(const Tuple& tp, As... as)
|
||||
-> decltype(ArgPack<N-1>::template mk<F,Tuple,decltype(std::get<N>(tp)),As...>(tp, std::get<N>(tp), as...))
|
||||
{
|
||||
return ArgPack<N-1>::template mk<F,Tuple,decltype(std::get<N>(tp)),As...>(tp, std::get<N>(tp), as...);
|
||||
}
|
||||
|
||||
template <class F, class Tuple, typename... As>
|
||||
static inline auto mkd(const F& ff, const Tuple& tp, As... as)
|
||||
-> decltype(ArgPack<N-1>::template mkd<F,Tuple,decltype(std::get<N>(tp)),As...>(ff, tp, std::get<N>(tp), as...))
|
||||
{
|
||||
return ArgPack<N-1>::template mkd<F,Tuple,decltype(std::get<N>(tp)),As...>(ff, tp, std::get<N>(tp), as...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ArgPack<0>
|
||||
{
|
||||
template <class F, class Tuple, typename... As>
|
||||
static inline auto mk(const Tuple& tp, As... as)
|
||||
-> decltype(F::apply(std::get<0>(tp), as...))
|
||||
{
|
||||
return F::apply(std::get<0>(tp), as...);
|
||||
}
|
||||
|
||||
template <class F, class Tuple, typename... As>
|
||||
static inline auto mkd(const F& ff, const Tuple& tp, As... as)
|
||||
-> decltype(ff(std::get<0>(tp), as...))
|
||||
{
|
||||
return ff(std::get<0>(tp), as...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, class F, typename... As>
|
||||
struct StaticFunctionBase
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
typedef T value_type;
|
||||
|
||||
template <class... Ops>
|
||||
static auto mk(const Ops&... ops)
|
||||
-> Operation<T,F,Ops...>
|
||||
{
|
||||
return Operation<T,F,Ops...>(ops...);
|
||||
}
|
||||
|
||||
static inline T apply(const std::tuple<As...>& arg)
|
||||
{
|
||||
return ArgPack<sizeof...(As)-1>::template mk<F,std::tuple<As...> >(arg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// OPERATIONS (STATIC)
|
||||
template <typename T>
|
||||
struct identity : public StaticFunctionBase<T, identity<T>, T>
|
||||
{
|
||||
//static constexpr bool FISSTATIC = true;
|
||||
using StaticFunctionBase<T, identity<T>, T>::apply;
|
||||
|
||||
static inline T apply(T a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
using plusv = decltype(std::declval<T>()+std::declval<U>());
|
||||
|
||||
template <typename T, typename U>
|
||||
using minusv = decltype(std::declval<T>()-std::declval<U>());
|
||||
|
||||
template <typename T, typename U>
|
||||
using multipliesv = decltype(std::declval<T>()*std::declval<U>());
|
||||
|
||||
template <typename T, typename U>
|
||||
using dividesv = decltype(std::declval<T>()/std::declval<U>());
|
||||
|
||||
template <typename T, typename U>
|
||||
struct plusx : public StaticFunctionBase<plusv<T,U>, plusx<T,U>, T, U>
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
using StaticFunctionBase<plusv<T,U>, plusx<T,U>, T, U>::apply;
|
||||
|
||||
static inline plusv<T,U> apply(T a1, U a2)
|
||||
{
|
||||
return a1 + a2;
|
||||
}
|
||||
|
||||
static inline T& selfApply(T& a1, const T& a2)
|
||||
{
|
||||
return a1 += a2;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct minusx : public StaticFunctionBase<minusv<T,U>, minusx<T,U>, T, U>
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
using StaticFunctionBase<minusv<T,U>, minusx<T,U>, T, U>::apply;
|
||||
|
||||
static inline plusv<T,U> apply(T a1, U a2)
|
||||
{
|
||||
return a1 - a2;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct multipliesx : public StaticFunctionBase<multipliesv<T,U>, multipliesx<T,U>, T, U>
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
using StaticFunctionBase<multipliesv<T,U>, multipliesx<T,U>, T, U>::apply;
|
||||
|
||||
static inline multipliesv<T,U> apply(T a1, U a2)
|
||||
{
|
||||
return a1 * a2;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct dividesx : public StaticFunctionBase<dividesv<T,U>, dividesx<T,U>, T, U>
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
using StaticFunctionBase<dividesv<T,U>, dividesx<T,U>, T, U>::apply;
|
||||
|
||||
static inline dividesv<T,U> apply(T a1, U a2)
|
||||
{
|
||||
return a1 / a2;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct negate : public StaticFunctionBase<T, negate<T>, T>
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
using StaticFunctionBase<T, negate<T>, T>::apply;
|
||||
|
||||
static inline T apply(T a)
|
||||
{
|
||||
return -a;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using plus = plusx<T,T>;
|
||||
|
||||
template <typename T>
|
||||
using minus = minusx<T,T>;
|
||||
|
||||
template <typename T>
|
||||
using multiplies = multipliesx<T,T>;
|
||||
|
||||
template <typename T>
|
||||
using divides = dividesx<T,T>;
|
||||
|
||||
/*
|
||||
template <typename T>
|
||||
struct plus : public StaticFunctionBase<T, plus<T>, T, T>
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
using StaticFunctionBase<T, plus<T>, T, T>::apply;
|
||||
|
||||
static inline T apply(T a1, T a2)
|
||||
{
|
||||
return a1 + a2;
|
||||
}
|
||||
|
||||
static inline T& selfApply(T& a1, const T& a2)
|
||||
{
|
||||
return a1 += a2;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct minus : public StaticFunctionBase<T, minus<T>, T, T>
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
using StaticFunctionBase<T, minus<T>, T, T>::apply;
|
||||
|
||||
static inline T apply(T a1, T a2)
|
||||
{
|
||||
return a1 - a2;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct multiplies : public StaticFunctionBase<T, multiplies<T>, T, T>
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
using StaticFunctionBase<T, multiplies<T>, T, T>::apply;
|
||||
|
||||
static inline T apply(T a1, T a2)
|
||||
{
|
||||
return a1 * a2;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct divides : public StaticFunctionBase<T, divides<T>, T, T>
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
using StaticFunctionBase<T, divides<T>, T, T>::apply;
|
||||
|
||||
static inline T apply(T a1, T a2)
|
||||
{
|
||||
return a1 / a2;
|
||||
}
|
||||
};
|
||||
*/
|
||||
// OPERATIONS (STATIC)
|
||||
template <typename R, typename... Args>
|
||||
class function
|
||||
{
|
||||
public:
|
||||
static constexpr bool FISSTATIC = false;
|
||||
|
||||
private:
|
||||
std::function<R(Args...)> mF;
|
||||
|
||||
public:
|
||||
|
||||
function() = default;
|
||||
function(const std::function<R(Args...)>& in) : mF(in) {}
|
||||
|
||||
inline R operator()(const Args&... args)
|
||||
{
|
||||
return mF(args...);
|
||||
}
|
||||
|
||||
inline R operator()(const std::tuple<Args...>& args)
|
||||
{
|
||||
return ArgPack<sizeof...(Args)-1>::template mkd<std::function<R(Args...)>,std::tuple<Args...>>>(mF, args);
|
||||
}
|
||||
};
|
||||
|
||||
#include <cmath>
|
||||
#define regFunc1(fff) template <typename T>\
|
||||
struct x_##fff : public StaticFunctionBase<T, x_##fff<T>, T> {\
|
||||
static constexpr bool FISSTATIC = true;\
|
||||
static inline T apply(T a){\
|
||||
return fff(a); } };
|
||||
|
||||
#include "extensions/math.h"
|
||||
#undef regFunc1
|
||||
|
||||
template <size_t N>
|
||||
struct x_ipow
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
|
||||
template <typename T>
|
||||
static inline T apply(T a)
|
||||
{
|
||||
return a * x_ipow<N-1>::apply(a);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct x_ipow<0>
|
||||
{
|
||||
static constexpr bool FISSTATIC = true;
|
||||
|
||||
template <typename T>
|
||||
static inline T apply(T a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
template <typename T, class Func>
|
||||
struct dynamic_function
|
||||
{
|
||||
static constexpr bool FISSTATIC = false;
|
||||
|
||||
template <typename... Us>
|
||||
inline T apply(Us... args)
|
||||
{
|
||||
return f(args...);
|
||||
}
|
||||
};
|
||||
*/
|
||||
} // end namespace MultiArrayHelper
|
||||
|
||||
#endif
|
|
@ -1,109 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/array/aindex.cc.h
|
||||
@brief Array index template implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_aindex_cc_h__
|
||||
#define __cxz_aindex_cc_h__
|
||||
|
||||
#include "aindex.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
AIndex<T>::AIndex(const T* data, const RangePtr& range, SizeT lexpos) :
|
||||
YIndex(range, lexpos),
|
||||
mCData(data)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
AIndex<T>::AIndex(const T* data, const YIndex& yindex) :
|
||||
YIndex(yindex),
|
||||
mCData(data)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
AIndex<T>::AIndex(const T* data, const AIndex<T>& aindex) :
|
||||
AIndex<T>(aindex)
|
||||
{
|
||||
mCData = data;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
AIndex<T> AIndex<T>::operator+(Int n) const
|
||||
{
|
||||
AIndex<T> o = *this;
|
||||
o += n;
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
AIndex<T> AIndex<T>::operator-(Int n) const
|
||||
{
|
||||
AIndex<T> o = *this;
|
||||
o -= n;
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& AIndex<T>::operator*() const
|
||||
{
|
||||
return mCData[IB::mPos];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* AIndex<T>::operator->() const
|
||||
{
|
||||
return mCData + IB::mPos;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
BIndex<T>::BIndex(T* data, const RangePtr& range, SizeT lexpos) :
|
||||
AIndex<T>(data, range, lexpos),
|
||||
mData(data)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
BIndex<T>::BIndex(T* data, const AIndex<T>& ai) :
|
||||
AIndex<T>(data, ai),
|
||||
mData(data)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
BIndex<T> BIndex<T>::operator+(Int n) const
|
||||
{
|
||||
BIndex<T> o = *this;
|
||||
o += n;
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
BIndex<T> BIndex<T>::operator-(Int n) const
|
||||
{
|
||||
BIndex<T> o = *this;
|
||||
o -= n;
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& BIndex<T>::operator*()
|
||||
{
|
||||
return mData[IB::mPos];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* BIndex<T>::operator->()
|
||||
{
|
||||
return mData + IB::mPos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/array/aindex.h
|
||||
@brief Array index declaration.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_aindex_h__
|
||||
#define __cxz_aindex_h__
|
||||
|
||||
#include "ranges/range_base.h"
|
||||
#include "ranges/index_base.h"
|
||||
#include "ranges/xindex.h"
|
||||
#include "ranges/yrange.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
// AIndex (A = Array)
|
||||
template <typename T>
|
||||
class AIndex : public YIndex
|
||||
{
|
||||
public:
|
||||
typedef YIndex::IB IB;
|
||||
using YIndex::operator=;
|
||||
|
||||
DEFAULT_MEMBERS(AIndex);
|
||||
AIndex(const T* data, const RangePtr& range, SizeT lexpos = 0);
|
||||
AIndex(const T* data, const YIndex& yindex);
|
||||
AIndex(const T* data, const AIndex<T>& aindex);
|
||||
|
||||
AIndex operator+(Int n) const;
|
||||
AIndex operator-(Int n) const;
|
||||
|
||||
const T& operator*() const;
|
||||
const T* operator->() const;
|
||||
|
||||
protected:
|
||||
const T* mCData = nullptr;
|
||||
|
||||
};
|
||||
|
||||
// BIndex (because B comes after A...)
|
||||
template <typename T>
|
||||
class BIndex : public AIndex<T>
|
||||
{
|
||||
public:
|
||||
typedef AIndex<T> AI;
|
||||
typedef typename AI::IB IB;
|
||||
|
||||
DEFAULT_MEMBERS(BIndex);
|
||||
BIndex(T* data, const RangePtr& range, SizeT pos = 0);
|
||||
BIndex(T* data, const AIndex<T>& cci);
|
||||
|
||||
BIndex operator+(Int n) const;
|
||||
BIndex operator-(Int n) const;
|
||||
|
||||
T& operator*();
|
||||
T* operator->();
|
||||
|
||||
private:
|
||||
T* mData = nullptr;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/array/array.cc.h
|
||||
@brief Array main header for template implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#include "array_base.cc.h"
|
||||
#include "marray.cc.h"
|
||||
#include "aindex.cc.h"
|
||||
#include "slice.cc.h"
|
|
@ -1,17 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/array/array.h
|
||||
@brief Array main header.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#include "array_base.h"
|
||||
#include "marray.h"
|
||||
#include "aindex.h"
|
||||
#include "slice.h"
|
||||
|
||||
#include "array.cc.h"
|
|
@ -1,382 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/array/array_base.cc.h
|
||||
@brief Array base class template implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_array_base_cc_h__
|
||||
#define __cxz_array_base_cc_h__
|
||||
|
||||
#include "array_base.h"
|
||||
#include "slice.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/*=======================================================+
|
||||
| Implementations for CArrayBase member functions |
|
||||
+=======================================================*/
|
||||
|
||||
template <typename T>
|
||||
CArrayBase<T>::CArrayBase(const RangePtr& range) :
|
||||
mRange(rangeCast<YRange>(range))
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
template <typename I, typename M>
|
||||
const T& CArrayBase<T>::operator[](const IndexInterface<I,M>& i) const
|
||||
{
|
||||
if(formatIsTrivial()){
|
||||
return data()[i.lex()];
|
||||
}
|
||||
else {
|
||||
auto ai = itLex(i);
|
||||
return *ai;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename I, typename M>
|
||||
const T& CArrayBase<T>::at(const IndexInterface<I,M>& i) const
|
||||
{
|
||||
auto ai = itLexSave(i);
|
||||
return *ai;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class... Indices>
|
||||
const T& CArrayBase<T>::operator[](const SPack<Indices...>& pack) const
|
||||
{
|
||||
if(formatIsTrivial()){
|
||||
return data()[pack.lex()];
|
||||
}
|
||||
else {
|
||||
auto ai = itLex(pack);
|
||||
return *ai;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class... Indices>
|
||||
const T& CArrayBase<T>::at(const SPack<Indices...>& pack) const
|
||||
{
|
||||
auto ai = itLexSave(pack);
|
||||
return *ai;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& CArrayBase<T>::operator[](const DPack& pack) const
|
||||
{
|
||||
auto ai = itLex(pack);
|
||||
return *ai;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& CArrayBase<T>::at(const DPack& pack) const
|
||||
{
|
||||
auto ai = itLexSave(pack);
|
||||
return *ai;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename I, typename M>
|
||||
Sptr<CArrayBase<T>> CArrayBase<T>::sl(const IndexInterface<I,M>& begin,
|
||||
const IndexInterface<I,M>& end) const
|
||||
{
|
||||
auto ai = itLexSave(begin);
|
||||
auto aj = itLexSave(end);
|
||||
return std::make_shared<CSlice<T>>(ai.prange(aj), this, ai.format(), ai.pos());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SizeT CArrayBase<T>::size() const
|
||||
{
|
||||
return mRange->size();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
RangePtr CArrayBase<T>::range() const
|
||||
{
|
||||
return mRange;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename CArrayBase<T>::const_iterator CArrayBase<T>::begin() const
|
||||
{
|
||||
return this->cbegin();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename CArrayBase<T>::const_iterator CArrayBase<T>::end() const
|
||||
{
|
||||
return this->cend();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class Index>
|
||||
COpRoot<T,Index> CArrayBase<T>::operator()(const Sptr<Index>& i) const
|
||||
{
|
||||
if(formatIsTrivial()){
|
||||
// assert that index format is trivial and has correct extensions
|
||||
CXZ_ASSERT(i->formatIsTrivial(),
|
||||
"got non-trivial index for container with trivial format");
|
||||
this->checkFormatCompatibility(*i);
|
||||
return coproot(*this, i);
|
||||
}
|
||||
else {
|
||||
if(i->formatIsTrivial()){
|
||||
// try to apply container format.
|
||||
// if the reformat changes the index type in any manner
|
||||
// the format is not applicable:
|
||||
if constexpr(std::is_same<decltype(i->reformat( Vector<SizeT>(), Vector<SizeT>() )),Index>::value){
|
||||
auto beg = begin();
|
||||
auto aformat = beg.deepFormat();
|
||||
auto amax = beg.deepMax();
|
||||
auto fi = i->reformat( aformat, amax );
|
||||
return coproot(*this, moveToPtr( fi ) );
|
||||
}
|
||||
else {
|
||||
this->checkFormatCompatibility(*i);
|
||||
return coproot(*this, i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// check if format is compatible
|
||||
this->checkFormatCompatibility(*i);
|
||||
return coproot(*this, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class... Indices>
|
||||
inline decltype(auto) CArrayBase<T>::operator()(const SPack<Indices...>& pack) const
|
||||
{
|
||||
return operator()(mindexPtr(pack));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline decltype(auto) CArrayBase<T>::operator()(const DPack& pack) const
|
||||
{
|
||||
return operator()(yindexPtr(pack));
|
||||
}
|
||||
|
||||
/*=================================================================+
|
||||
| Implementations for protected CArrayBase member functions |
|
||||
+=================================================================*/
|
||||
|
||||
template <typename T>
|
||||
template <class Acc>
|
||||
typename CArrayBase<T>::const_iterator CArrayBase<T>::itLex(const Acc& acc) const
|
||||
{
|
||||
return begin() + acc.lex();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class Acc>
|
||||
typename CArrayBase<T>::const_iterator CArrayBase<T>::itLexSave(const Acc& acc) const
|
||||
{
|
||||
CXZ_ASSERT(acc.lex() < this->size(), "index out of range");
|
||||
// check further compatibility of index/range format!!!
|
||||
return begin() + acc.lex();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class Acc>
|
||||
void CArrayBase<T>::checkFormatCompatibility(const Acc& acc) const
|
||||
{
|
||||
auto j = begin();
|
||||
CXZ_ASSERT(acc.lmax().val() == j.lmax().val(),
|
||||
"got index of iteration space size = " << acc.lmax().val()
|
||||
<< ", expected size = " << acc.lmax().val());
|
||||
Vector<SizeT> f1 = toVec(acc.deepFormat());
|
||||
Vector<SizeT> f2 = j.deepFormat();
|
||||
std::sort(f1.begin(),f1.end());
|
||||
std::sort(f2.begin(),f2.end());
|
||||
SizeT i1 = 0;
|
||||
SizeT i2 = 0;
|
||||
CXZ_ASSERT(f1[i1] == f2[i2], "obtained format " << toString(f1)
|
||||
<< ", which is incompatible to target format " << toString(f2));
|
||||
++i1;
|
||||
++i2;
|
||||
while(i1 < f1.size() and i2 < f2.size()){
|
||||
if(f1[i1] < f2[i2]) {
|
||||
if(++i1 == f1.size()) break;
|
||||
CXZ_ASSERT(f1[i1] <= f2[i2], "obtained format " << toString(f1)
|
||||
<< ", which is incompatible to target format " << toString(f2));
|
||||
}
|
||||
else if(f1[i1] > f2[i2]) {
|
||||
if(++i2 == f2.size()) break;
|
||||
CXZ_ASSERT(f1[i1] >= f2[i2], "obtained format " << toString(f1)
|
||||
<< ", which is incompatible to target format " << toString(f2));
|
||||
}
|
||||
else {
|
||||
++i1;
|
||||
++i2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*======================================================+
|
||||
| Implementations for ArrayBase member functions |
|
||||
+======================================================*/
|
||||
|
||||
template <typename T>
|
||||
ArrayBase<T>::ArrayBase(const RangePtr& range) :
|
||||
CArrayBase<T>(range)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
template <typename I, typename M>
|
||||
T& ArrayBase<T>::operator[](const IndexInterface<I,M>& i)
|
||||
{
|
||||
if(this->formatIsTrivial()){
|
||||
return data()[i.lex()];
|
||||
}
|
||||
else {
|
||||
auto ai = itLex(i);
|
||||
return *ai;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename I, typename M>
|
||||
T& ArrayBase<T>::at(const IndexInterface<I,M>& i)
|
||||
{
|
||||
auto ai = itLexSave(i);
|
||||
return *ai;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class... Indices>
|
||||
T& ArrayBase<T>::operator[](const SPack<Indices...>& pack)
|
||||
{
|
||||
if(this->formatIsTrivial()){
|
||||
return data()[pack.lex()];
|
||||
}
|
||||
else {
|
||||
auto ai = itLex(pack);
|
||||
return *ai;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class... Indices>
|
||||
T& ArrayBase<T>::at(const SPack<Indices...>& pack)
|
||||
{
|
||||
auto ai = itLexSave(pack);
|
||||
return *ai;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& ArrayBase<T>::operator[](const DPack& pack)
|
||||
{
|
||||
auto ai = itLex(pack);
|
||||
return *ai;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& ArrayBase<T>::at(const DPack& pack)
|
||||
{
|
||||
auto ai = itLexSave(pack);
|
||||
return *ai;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename I, typename M>
|
||||
Sptr<ArrayBase<T>> ArrayBase<T>::sl(const IndexInterface<I,M>& begin,
|
||||
const IndexInterface<I,M>& end)
|
||||
{
|
||||
auto ai = itLexSave(begin);
|
||||
auto aj = itLexSave(end);
|
||||
return std::make_shared<Slice<T>>(ai.prange(aj), this, ai.format(), ai.pos());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename ArrayBase<T>::iterator ArrayBase<T>::begin()
|
||||
{
|
||||
return iterator(this->data(), this->cbegin());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename ArrayBase<T>::iterator ArrayBase<T>::end()
|
||||
{
|
||||
return iterator(this->data(), this->cend());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class Index>
|
||||
OpRoot<T,Index> ArrayBase<T>::operator()(const Sptr<Index>& i)
|
||||
{
|
||||
if(this->formatIsTrivial()){
|
||||
// assert that index format is trivial and has correct extensions
|
||||
CXZ_ASSERT(i->formatIsTrivial(),
|
||||
"got non-trivial index for container with trivial format");
|
||||
this->checkFormatCompatibility(*i);
|
||||
return oproot(*this, i);
|
||||
}
|
||||
else {
|
||||
if(i->formatIsTrivial()){
|
||||
// try to apply container format.
|
||||
// if the reformat changes the index type in any manner
|
||||
// the format is not applicable:
|
||||
if constexpr(std::is_same<decltype(i->reformat( Vector<SizeT>(), Vector<SizeT>() )),Index>::value){
|
||||
auto beg = begin();
|
||||
auto aformat = beg.deepFormat();
|
||||
auto amax = beg.deepMax();
|
||||
auto fi = i->reformat( aformat, amax );
|
||||
return oproot(*this, moveToPtr( fi ) );
|
||||
}
|
||||
else {
|
||||
this->checkFormatCompatibility(*i);
|
||||
return oproot(*this, i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// check if format is compatible
|
||||
this->checkFormatCompatibility(*i);
|
||||
return oproot(*this, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class... Indices>
|
||||
inline decltype(auto) ArrayBase<T>::operator()(const SPack<Indices...>& pack)
|
||||
{
|
||||
return operator()(mindexPtr(pack));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline decltype(auto) ArrayBase<T>::operator()(const DPack& pack)
|
||||
{
|
||||
return operator()(yindexPtr(pack));
|
||||
}
|
||||
|
||||
/*================================================================+
|
||||
| Implementations for protected ArrayBase member functions |
|
||||
+================================================================*/
|
||||
|
||||
template <typename T>
|
||||
template <class Acc>
|
||||
typename ArrayBase<T>::iterator ArrayBase<T>::itLex(const Acc& acc)
|
||||
{
|
||||
return begin() + acc.lex();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <class Acc>
|
||||
typename ArrayBase<T>::iterator ArrayBase<T>::itLexSave(const Acc& acc)
|
||||
{
|
||||
CXZ_ASSERT(acc.lex() < this->size(), "index out of range");
|
||||
// check further compatibility of index/range format!!!
|
||||
return begin() + acc.lex();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,290 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/array/array_base.h
|
||||
@brief Array base class declarations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_array_base_h__
|
||||
#define __cxz_array_base_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/base.h"
|
||||
#include "aindex.h"
|
||||
#include "operation/op_types.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** ****
|
||||
Abstract container base class
|
||||
only read access to the data
|
||||
|
||||
@tparam T data type
|
||||
*/
|
||||
template <typename T>
|
||||
class CArrayBase
|
||||
{
|
||||
public:
|
||||
typedef AIndex<T> const_iterator; /** const iterator type */
|
||||
|
||||
DEFAULT_MEMBERS(CArrayBase); /**< default constructors and assignments */
|
||||
|
||||
/** construct container on a range
|
||||
@param range
|
||||
*/
|
||||
CArrayBase(const RangePtr& range);
|
||||
|
||||
/** default destructor */
|
||||
virtual ~CArrayBase() = default;
|
||||
|
||||
/** const data element access
|
||||
@tparam I index type
|
||||
@tparam M meta data type
|
||||
@param i index
|
||||
*/
|
||||
template <typename I, typename M>
|
||||
const T& operator[](const IndexInterface<I,M>& i) const;
|
||||
|
||||
/** const data element access
|
||||
performs compatibility checks
|
||||
@tparam I index type
|
||||
@tparam M meta data type
|
||||
@param i index
|
||||
*/
|
||||
template <typename I, typename M>
|
||||
const T& at(const IndexInterface<I,M>& i) const;
|
||||
|
||||
/** const data element access
|
||||
@tparam I index type
|
||||
@tparam M meta data type
|
||||
@param pack static index pack
|
||||
*/
|
||||
template <class... Indices>
|
||||
const T& operator[](const SPack<Indices...>& pack) const;
|
||||
|
||||
/** const data element access
|
||||
performs compatibility checks
|
||||
@tparam I index type
|
||||
@tparam M meta data type
|
||||
@param i static index pack
|
||||
*/
|
||||
template <class... Indices>
|
||||
const T& at(const SPack<Indices...>& pack) const;
|
||||
|
||||
/** const data element access
|
||||
@param pack index pack
|
||||
*/
|
||||
const T& operator[](const DPack& pack) const;
|
||||
|
||||
/** const data element access
|
||||
performs compatibility checks
|
||||
@param i index pack
|
||||
*/
|
||||
const T& at(const DPack& pack) const;
|
||||
|
||||
/** create hypercubic slice from this container
|
||||
@tparam I type of index used to indicate slice edges
|
||||
@tparam M index meta type
|
||||
@param begin begin edge
|
||||
@param end end edge
|
||||
*/
|
||||
template <typename I, typename M>
|
||||
Sptr<CArrayBase<T>> sl(const IndexInterface<I,M>& begin,
|
||||
const IndexInterface<I,M>& end) const;
|
||||
|
||||
/** create operation on this container
|
||||
@tparam Index type of operation index
|
||||
@param i operation index
|
||||
*/
|
||||
template <class Index>
|
||||
COpRoot<T,Index> operator()(const Sptr<Index>& i) const;
|
||||
|
||||
/** create operation on this container
|
||||
@tparam Indices types of operation indices
|
||||
@param pack pack of operation index
|
||||
*/
|
||||
template <class... Indices>
|
||||
inline decltype(auto) operator()(const SPack<Indices...>& pack) const;
|
||||
|
||||
/** create operation on this container
|
||||
@param pack pack of operation index
|
||||
*/
|
||||
inline decltype(auto) operator()(const DPack& pack) const;
|
||||
|
||||
/** get pointer to container data */
|
||||
virtual const T* data() const = 0;
|
||||
|
||||
/** get number of elements in the container */
|
||||
virtual SizeT size() const;
|
||||
|
||||
/** get container range */
|
||||
virtual RangePtr range() const;
|
||||
|
||||
/** get index pointing to first position */
|
||||
virtual const_iterator begin() const;
|
||||
|
||||
/** get index pointing to position after last position */
|
||||
virtual const_iterator end() const;
|
||||
|
||||
/** get index pointing to first position */
|
||||
virtual const_iterator cbegin() const = 0;
|
||||
|
||||
/** get index pointing to position after last position */
|
||||
virtual const_iterator cend() const = 0;
|
||||
|
||||
/** check if container views the data, i.e. it does not own it */
|
||||
virtual bool isView() const = 0;
|
||||
|
||||
protected:
|
||||
RangePtr mRange; /**< the container range */
|
||||
|
||||
/** Get valid data index.
|
||||
Create well-formated index from index pack (unformatted)
|
||||
or index using trivial format.
|
||||
@tparam Acc index type or index pack type
|
||||
@param acc index or index pack
|
||||
*/
|
||||
template <class Acc>
|
||||
const_iterator itLex(const Acc& acc) const;
|
||||
|
||||
/** Get valid data index.
|
||||
Create well-formated index from index pack (unformatted)
|
||||
or index using trivial format.
|
||||
Perform compatibility checks.
|
||||
@tparam Acc index type or index pack type
|
||||
@param acc index or index pack
|
||||
*/
|
||||
template <class Acc>
|
||||
const_iterator itLexSave(const Acc& acc) const;
|
||||
|
||||
/** Perform compatibility checks
|
||||
@tparam Acc index type or index pack type
|
||||
@param acc index or index pack.
|
||||
*/
|
||||
template <class Acc>
|
||||
void checkFormatCompatibility(const Acc& acc) const;
|
||||
|
||||
/** check if format is trivial
|
||||
@return true if container is data owning array, else return
|
||||
result of the corresponding container index
|
||||
*/
|
||||
virtual bool formatIsTrivial() const = 0;
|
||||
};
|
||||
|
||||
/** ****
|
||||
Abstract container base class
|
||||
read and write access to the data
|
||||
|
||||
@tparam T data type
|
||||
*/
|
||||
template <typename T>
|
||||
class ArrayBase : public CArrayBase<T>
|
||||
{
|
||||
public:
|
||||
typedef CArrayBase<T> CAB;
|
||||
typedef typename CAB::const_iterator const_iterator; /**< constant iterator type */
|
||||
typedef BIndex<T> iterator; /**< read/write iterator type */
|
||||
|
||||
using CAB::operator[];
|
||||
using CAB::operator();
|
||||
using CAB::at;
|
||||
using CAB::data;
|
||||
using CAB::begin;
|
||||
using CAB::end;
|
||||
using CAB::cbegin;
|
||||
using CAB::cend;
|
||||
using CAB::sl;
|
||||
|
||||
DEFAULT_MEMBERS(ArrayBase); /**< default constructors and assignments */
|
||||
|
||||
/** construct a container on a range
|
||||
*/
|
||||
ArrayBase(const RangePtr& range);
|
||||
|
||||
/** @copydoc CArrayBase::operator[]()
|
||||
*/
|
||||
template <typename I, typename M>
|
||||
T& operator[](const IndexInterface<I,M>& i);
|
||||
|
||||
/** @copydoc CArrayBase::at()
|
||||
*/
|
||||
template <typename I, typename M>
|
||||
T& at(const IndexInterface<I,M>& i);
|
||||
|
||||
/** @copydoc CArrayBase::operator[]()
|
||||
*/
|
||||
template <class... Indices>
|
||||
T& operator[](const SPack<Indices...>& pack);
|
||||
|
||||
/** @copydoc CArrayBase::at()
|
||||
*/
|
||||
template <class... Indices>
|
||||
T& at(const SPack<Indices...>& pack);
|
||||
|
||||
/** @copydoc CArrayBase::operator[]()
|
||||
*/
|
||||
T& operator[](const DPack& pack);
|
||||
|
||||
/** @copydoc CArrayBase::at()
|
||||
*/
|
||||
T& at(const DPack& pack);
|
||||
|
||||
/** @copydoc CArrayBase::operator()()
|
||||
*/
|
||||
template <class Index>
|
||||
OpRoot<T,Index> operator()(const Sptr<Index>& i);
|
||||
|
||||
/** @copydoc CArrayBase::operator()()
|
||||
*/
|
||||
template <class... Indices>
|
||||
inline decltype(auto) operator()(const SPack<Indices...>& pack);
|
||||
|
||||
/** @copydoc CArrayBase::operator()()
|
||||
*/
|
||||
inline decltype(auto) operator()(const DPack& pack);
|
||||
|
||||
/** @copydoc CArrayBase::sl()
|
||||
*/
|
||||
template <typename I, typename M>
|
||||
Sptr<ArrayBase<T>> sl(const IndexInterface<I,M>& begin,
|
||||
const IndexInterface<I,M>& end);
|
||||
|
||||
/** @copydoc CArrayBase::data()
|
||||
read/write access
|
||||
*/
|
||||
virtual T* data() = 0;
|
||||
|
||||
/** @copydoc CArrayBase::begin()
|
||||
read/write access
|
||||
*/
|
||||
virtual iterator begin();
|
||||
|
||||
/** @copydoc CArrayBase::end()
|
||||
read/write access
|
||||
*/
|
||||
virtual iterator end();
|
||||
|
||||
protected:
|
||||
|
||||
/** @copydoc CArrayBase::itLex()
|
||||
*/
|
||||
template <class Acc>
|
||||
iterator itLex(const Acc& acc);
|
||||
|
||||
/** @copydoc CArrayBase::itLexSave()
|
||||
*/
|
||||
template <class Acc>
|
||||
iterator itLexSave(const Acc& acc);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,105 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/array/marray.cc.h
|
||||
@brief MArray implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_marray_cc_h__
|
||||
#define __cxz_marray_cc_h__
|
||||
|
||||
#include "marray.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/*=======================================================+
|
||||
| Implementation of MArray public member functions |
|
||||
+=======================================================*/
|
||||
|
||||
template <typename T>
|
||||
MArray<T>::MArray(const RangePtr& range) :
|
||||
ArrayBase<T>(range), mCont(range->size())
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
MArray<T>::MArray(const RangePtr& range, const Vector<T>& vec) :
|
||||
ArrayBase<T>(range), mCont(vec)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
MArray<T>::MArray(const RangePtr& range, Vector<T>&& vec) :
|
||||
ArrayBase<T>(range), mCont(vec)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
MArray<T>& MArray<T>::init(const RangePtr& range)
|
||||
{
|
||||
AB::mRange = rangeCast<YRange>(range);
|
||||
mCont.resize(AB::mRange->size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
MArray<T>& MArray<T>::extend(const RangePtr& range)
|
||||
{
|
||||
if(AB::mRange == nullptr) {
|
||||
return this->init(range);
|
||||
}
|
||||
MArray<T> tmp(AB::mRange->extend(range));
|
||||
auto ei = this->end();
|
||||
auto ti = tmp.begin();
|
||||
// this is not very efficient; remove by sub-index operation once available:
|
||||
for(auto ii = this->begin(); ii != ei; ++ii){
|
||||
ti.at(ii.meta());
|
||||
*ti = *ii;
|
||||
}
|
||||
*this = std::move(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* MArray<T>::data() const
|
||||
{
|
||||
return mCont.data();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* MArray<T>::data()
|
||||
{
|
||||
return mCont.data();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename MArray<T>::const_iterator MArray<T>::cbegin() const
|
||||
{
|
||||
return const_iterator(mCont.data(), AB::mRange);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename MArray<T>::const_iterator MArray<T>::cend() const
|
||||
{
|
||||
return const_iterator(mCont.data(), AB::mRange, mCont.size());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool MArray<T>::isView() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*==========================================================+
|
||||
| Implementation of MArray protected member functions |
|
||||
+==========================================================*/
|
||||
|
||||
template <typename T>
|
||||
bool MArray<T>::formatIsTrivial() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/array/marray.h
|
||||
@brief MArray declarations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_marray_h__
|
||||
#define __cxz_marray_h__
|
||||
|
||||
#include "array_base.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
/** ***
|
||||
Generic multi-dimensional array class
|
||||
This class owns the data that can be accessed through it
|
||||
**/
|
||||
template <typename T>
|
||||
class MArray : public ArrayBase<T>
|
||||
{
|
||||
public:
|
||||
typedef CArrayBase<T> AB;
|
||||
typedef typename AB::const_iterator const_iterator;
|
||||
|
||||
using CArrayBase<T>::operator[];
|
||||
using ArrayBase<T>::operator[];
|
||||
|
||||
DEFAULT_MEMBERS(MArray);
|
||||
MArray(const RangePtr& range);
|
||||
MArray(const RangePtr& range, const Vector<T>& vec);
|
||||
MArray(const RangePtr& range, Vector<T>&& vec);
|
||||
MArray& init(const RangePtr& range);
|
||||
MArray& extend(const RangePtr& range);
|
||||
|
||||
virtual const T* data() const override;
|
||||
virtual T* data() override;
|
||||
virtual const_iterator cbegin() const override;
|
||||
virtual const_iterator cend() const override;
|
||||
virtual bool isView() const override;
|
||||
|
||||
SERIALIZATION_FUNCTIONS;
|
||||
|
||||
protected:
|
||||
virtual bool formatIsTrivial() const override final;
|
||||
|
||||
private:
|
||||
Vector<T> mCont;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,120 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/array/slice.cc.h
|
||||
@brief Slice implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_slice_cc_h__
|
||||
#define __cxz_slice_cc_h__
|
||||
|
||||
#include "slice.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/*========================================================+
|
||||
| Implementation of public CSlice member functions |
|
||||
+========================================================*/
|
||||
|
||||
template <typename T>
|
||||
CSlice<T>::CSlice(const RangePtr& range, const CArrayBase<T>* parent,
|
||||
const YFormat& blockSizes, SizeT off) :
|
||||
CArrayBase<T>(range),
|
||||
mCParent(parent),
|
||||
mBlockSizes(blockSizes),
|
||||
mOff(off)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
const T* CSlice<T>::data() const
|
||||
{
|
||||
return mCParent->data() + mOff;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename CSlice<T>::const_iterator CSlice<T>::cbegin() const
|
||||
{
|
||||
return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, 0));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename CSlice<T>::const_iterator CSlice<T>::cend() const
|
||||
{
|
||||
return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, AB::mRange->size()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool CSlice<T>::isView() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================+
|
||||
| Implementation of protected CSlice member functions |
|
||||
+===========================================================*/
|
||||
|
||||
template <typename T>
|
||||
bool CSlice<T>::formatIsTrivial() const
|
||||
{
|
||||
return cbegin().formatIsTrivial();
|
||||
}
|
||||
|
||||
/*=======================================================+
|
||||
| Implementation of public Slice member functions |
|
||||
+=======================================================*/
|
||||
|
||||
template <typename T>
|
||||
Slice<T>::Slice(const RangePtr& range, ArrayBase<T>* parent,
|
||||
const YFormat& blockSizes, SizeT off) :
|
||||
ArrayBase<T>(range),
|
||||
mParent(parent),
|
||||
mBlockSizes(blockSizes),
|
||||
mOff(off)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
T* Slice<T>::data()
|
||||
{
|
||||
return mParent->data() + mOff;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* Slice<T>::data() const
|
||||
{
|
||||
return mParent->data() + mOff;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename Slice<T>::const_iterator Slice<T>::cbegin() const
|
||||
{
|
||||
return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, 0));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename Slice<T>::const_iterator Slice<T>::cend() const
|
||||
{
|
||||
return const_iterator(data(),YIndex(AB::mRange, mBlockSizes, AB::mRange->size()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Slice<T>::isView() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*==========================================================+
|
||||
| Implementation of protected Slice member functions |
|
||||
+==========================================================*/
|
||||
|
||||
template <typename T>
|
||||
bool Slice<T>::formatIsTrivial() const
|
||||
{
|
||||
return cbegin().formatIsTrivial();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,102 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/array/slice.h
|
||||
@brief Slice declarations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_slice_h__
|
||||
#define __cxz_slice_h__
|
||||
|
||||
#include "base/base.h"
|
||||
#include "array_base.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** ****
|
||||
constant and possibly partial view on the data
|
||||
of another container
|
||||
|
||||
@tparam T data type
|
||||
*/
|
||||
template <typename T>
|
||||
class CSlice : public CArrayBase<T>
|
||||
{
|
||||
public:
|
||||
typedef CArrayBase<T> AB;
|
||||
typedef typename AB::const_iterator const_iterator;
|
||||
|
||||
DEFAULT_MEMBERS(CSlice); /**< default constructors and assignments */
|
||||
|
||||
/** create slice from an array
|
||||
|
||||
@param range the slice's container range
|
||||
@param parent the original container
|
||||
@param blockSizes the format of the slice
|
||||
@param off the initial pointer position w.r.t. the original initial position
|
||||
*/
|
||||
CSlice(const RangePtr& range, const CArrayBase<T>* parent,
|
||||
const YFormat& blockSizes, SizeT off);
|
||||
|
||||
virtual const T* data() const override;
|
||||
virtual const_iterator cbegin() const override;
|
||||
virtual const_iterator cend() const override;
|
||||
virtual bool isView() const override final;
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool formatIsTrivial() const override final;
|
||||
|
||||
const CArrayBase<T>* mCParent = nullptr; /**< pointer to the original container */
|
||||
YFormat mBlockSizes; /**< the format */
|
||||
SizeT mOff = 0; /** pointer offset w.r.t. the original pointer */
|
||||
|
||||
};
|
||||
|
||||
/** ****
|
||||
possibly partial view on the data
|
||||
of another container
|
||||
|
||||
@tparam T data type
|
||||
*/
|
||||
template <typename T>
|
||||
class Slice : public ArrayBase<T>
|
||||
{
|
||||
public:
|
||||
typedef CArrayBase<T> AB;
|
||||
typedef typename AB::const_iterator const_iterator;
|
||||
|
||||
DEFAULT_MEMBERS(Slice); /**< default constructors and assignments */
|
||||
|
||||
/** create slice from an array
|
||||
|
||||
@param range the slice's container range
|
||||
@param parent the original container
|
||||
@param blockSizes the format of the slice
|
||||
@param off the initial pointer position w.r.t. the original initial position
|
||||
*/
|
||||
Slice(const RangePtr& range, ArrayBase<T>* parent,
|
||||
const YFormat& blockSizes, SizeT off);
|
||||
|
||||
virtual const T* data() const override;
|
||||
virtual T* data() override;
|
||||
virtual const_iterator cbegin() const override;
|
||||
virtual const_iterator cend() const override;
|
||||
virtual bool isView() const override final;
|
||||
|
||||
protected:
|
||||
virtual bool formatIsTrivial() const override final;
|
||||
|
||||
private:
|
||||
ArrayBase<T>* mParent = nullptr;
|
||||
YFormat mBlockSizes;
|
||||
SizeT mOff = 0;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,40 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/assert.h
|
||||
@brief warning and error makros
|
||||
|
||||
Definition of macros that can be used for convenient error handling and warnings
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
/** library error tag */
|
||||
#define CXZ_ERRTAG __FILE__ << '@' << __LINE__ << '(' << __func__ << "): error"
|
||||
|
||||
/** library warning tag */
|
||||
#define CXZ_WARNTAG __FILE__ << '@' << __LINE__ << ": warning"
|
||||
|
||||
/** throw error
|
||||
@param errmsg error message
|
||||
*/
|
||||
#define CXZ_ERROR(errmsg) { \
|
||||
auto mkerr = [&](){ std::stringstream ss; ss << CXZ_ERRTAG << ": " << errmsg << std::flush; return ss.str(); }; \
|
||||
throw std::runtime_error(mkerr()); }
|
||||
|
||||
/** print warning
|
||||
@param errmsg warning message
|
||||
*/
|
||||
#define CXZ_WARNING(errmsg) {\
|
||||
std::cerr << CXZ_WARNTAG << ": " << errmsg << std::endl; }
|
||||
|
||||
/** throw error if given statement is not fulfilled
|
||||
@param statement statement to be checked
|
||||
@param errmsg error message
|
||||
*/
|
||||
#define CXZ_ASSERT(statement, errmsg) if(not (statement)) { CXZ_ERROR(errmsg); }
|
|
@ -1,18 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/base.cc.h
|
||||
@brief basic cc headers
|
||||
|
||||
Include basic cc headers containing defintions and macros
|
||||
used throughout this library
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#include "dtype.cc.h"
|
||||
#include "obj_handle.cc.h"
|
||||
#include "to_string.cc.h"
|
||||
#include "iter.cc.h"
|
|
@ -1,38 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/base.h
|
||||
@brief basic headers
|
||||
|
||||
Include basic headers containing defintions and macros
|
||||
used throughout this library
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_base_h__
|
||||
#define __cxz_base_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
#include "macros.h"
|
||||
#include "assert.h"
|
||||
#include "types.h"
|
||||
#include "obj_handle.h"
|
||||
#include "dtype.h"
|
||||
#include "isq.h"
|
||||
#include "iter.h"
|
||||
#include "uuid.h"
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include "intrin.h"
|
||||
|
||||
#include "base.cc.h"
|
||||
|
||||
#include "memory/memory.h"
|
||||
|
||||
#endif
|
|
@ -1,35 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/config.h
|
||||
@brief Runtime config functions declarations.
|
||||
|
||||
Declare functions returning version and configuration infos.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_config_h__
|
||||
#define __cxz_config_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include "base/types.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
namespace Config
|
||||
{
|
||||
/** return cnorxz version */
|
||||
String version();
|
||||
|
||||
/** return git hash */
|
||||
String commit();
|
||||
|
||||
/** return compile flags */
|
||||
String flags();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,74 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/dtype.cc.h
|
||||
@brief DType template member function definitions
|
||||
|
||||
Definitions of the template member functions of the DType class.
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_dtype_cc_h__
|
||||
#define __cxz_dtype_cc_h__
|
||||
|
||||
#include <sstream>
|
||||
#include "dtype.h"
|
||||
#include "to_string.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
// for tuple use vector<DType> !!!
|
||||
// (yes DType is slow, thats why one should only use it for debugging)
|
||||
|
||||
template <typename T>
|
||||
DType::DType(const T& d) : mD(d)
|
||||
{
|
||||
_mkToStr<T>();
|
||||
_mkComp<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DType& DType::operator=(const T& d)
|
||||
{
|
||||
mD = d;
|
||||
_mkToStr<T>();
|
||||
_mkComp<T>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DType::_mkToStr()
|
||||
{
|
||||
mToStr = [](const std::any& d){
|
||||
return toString(std::any_cast<T>(d));
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DType::_mkComp()
|
||||
{
|
||||
mComp = [](const std::any& d, const std::any& a){
|
||||
if(d.type() != a.type()){
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
auto& at = std::any_cast<const T&>(a);
|
||||
auto& dt = std::any_cast<const T&>(d);
|
||||
if(std::equal_to<T>{}(dt,at)){
|
||||
return 0;
|
||||
}
|
||||
else if(std::less<T>{}(dt,at)){
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,104 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/dtype.h
|
||||
@brief DType declaration
|
||||
|
||||
DType is a generic type-erasing class that wrapps std::any.
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_dynamic_meta_h__
|
||||
#define __cxz_dynamic_meta_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <any>
|
||||
#include <functional>
|
||||
|
||||
#include "macros.h"
|
||||
#include "types.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** ****
|
||||
Type erasing class wrapping std::any
|
||||
*/
|
||||
class DType
|
||||
{
|
||||
private:
|
||||
std::any mD;
|
||||
std::function<String(const std::any&)> mToStr;
|
||||
std::function<Int(const std::any&,const std::any&)> mComp;
|
||||
|
||||
template <typename T>
|
||||
void _mkToStr();
|
||||
|
||||
template <typename T>
|
||||
void _mkComp();
|
||||
|
||||
public:
|
||||
DEFAULT_MEMBERS(DType); /**< default constructors and assignments */
|
||||
|
||||
/** Generic constructor template
|
||||
|
||||
Constructs a DType from the given argument
|
||||
@tparam T input data type
|
||||
@param d input
|
||||
*/
|
||||
template <typename T>
|
||||
DType(const T& d);
|
||||
|
||||
/** Generic assignment template
|
||||
|
||||
Assigns the given argument to the DType
|
||||
@tparam T input data type
|
||||
@param d input
|
||||
*/
|
||||
template <typename T>
|
||||
DType& operator=(const T& d);
|
||||
|
||||
/** convert contained data so string */
|
||||
String str() const { return mToStr(mD); }
|
||||
|
||||
/** return reference to type-erased data */
|
||||
const std::any& get() const { return mD; }
|
||||
|
||||
/** check for equality
|
||||
@param a variable to compare with
|
||||
*/
|
||||
bool operator==(const DType& a) const { return mComp(mD,a.mD) == 0; }
|
||||
|
||||
/** check for inequality
|
||||
@param a variable to compare with
|
||||
*/
|
||||
bool operator!=(const DType& a) const { return mComp(mD,a.mD) != 0; }
|
||||
|
||||
/** check smaller
|
||||
@param a variable to compare with
|
||||
*/
|
||||
bool operator<(const DType& a) const { return mComp(mD,a.mD) == -1; }
|
||||
|
||||
/** check greater
|
||||
@param a variable to compare with
|
||||
*/
|
||||
bool operator>(const DType& a) const { return mComp(mD,a.mD) == 1; }
|
||||
|
||||
/** check not greater
|
||||
@param a variable to compare with
|
||||
*/
|
||||
bool operator<=(const DType& a) const { auto c = mComp(mD,a.mD); return c <= 0; }
|
||||
|
||||
/** check not smaller
|
||||
@param a variable to compare with
|
||||
*/
|
||||
bool operator>=(const DType& a) const { auto c = mComp(mD,a.mD); return c == 1 or c == 0; }
|
||||
};
|
||||
|
||||
} // namespace CNORXZ
|
||||
|
||||
#endif
|
|
@ -1,25 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
@file include/base/intrin.h
|
||||
@brief Definitions related to intrinsics
|
||||
**/
|
||||
|
||||
#ifndef __cxz_intrin_h__
|
||||
#define __cxz_intrin_h__
|
||||
|
||||
#define MAX_VSIZE 1
|
||||
|
||||
// AVX:
|
||||
|
||||
#define AVX_BITS 256
|
||||
#define AVX_VSIZE (AVX_BITS/8)
|
||||
#ifdef CXZ_HAVE_AVX
|
||||
#undef MAX_VSIZE
|
||||
#define MAX_VSIZE AVX_VSIZE
|
||||
#endif
|
||||
|
||||
// ...:
|
||||
|
||||
// ...
|
||||
|
||||
#endif
|
|
@ -1,48 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/isq.h
|
||||
@brief Integer sequence range and creation functions
|
||||
|
||||
Declaration of integer sequence range and corresponding creating function templates
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_isq_h__
|
||||
#define __cxz_isq_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <utility>
|
||||
#include "types.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** @cond 0 */
|
||||
template <SizeT O, SizeT... Is>
|
||||
std::index_sequence<(Is+O)...> mkIsqAdd(std::index_sequence<Is...> is) { return {}; }
|
||||
|
||||
template <SizeT B, SizeT E>
|
||||
struct MkIsq
|
||||
{
|
||||
static auto make()
|
||||
{
|
||||
static_assert(B <= E, "begin of sequence must be smaller than end of sequence");
|
||||
return mkIsqAdd<B>( std::make_index_sequence<E-B>{} );
|
||||
}
|
||||
|
||||
typedef decltype(make()) type;
|
||||
};
|
||||
/** @endcond */
|
||||
|
||||
/** static consecutive integer sequence
|
||||
@tparam B begin integer
|
||||
@tparam E end integer
|
||||
*/
|
||||
template <SizeT B, SizeT E>
|
||||
using Isqr = typename MkIsq<B,E>::type;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,69 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/iter.cc.h
|
||||
@brief Static for-loops
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_iter_cc_h__
|
||||
#define __cxz_iter_cc_h__
|
||||
|
||||
#include "iter.h"
|
||||
#include "xpr/func.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** @cond 0 */
|
||||
template <class G, class F, SizeT... Is>
|
||||
constexpr decltype(auto) iteri(const G& g, const F& f, Isq<Is...> is)
|
||||
{
|
||||
if constexpr(std::is_same<F,NoF>::value){
|
||||
( g(CSizeT<Is>{}), ... );
|
||||
}
|
||||
else {
|
||||
return f( g(CSizeT<Is>{}) ... );
|
||||
}
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
template <SizeT B, SizeT E, class G, class F>
|
||||
constexpr decltype(auto) iter(const G& g, const F& f)
|
||||
{
|
||||
return iteri(g, f, Isqr<B,E>{});
|
||||
}
|
||||
|
||||
/** @cond 0 */
|
||||
template <SizeT E, SizeT I, class G, class F, class C, typename... Args>
|
||||
constexpr decltype(auto) iterIfi(const G& g, const F& f, const C& c, const Args&... args)
|
||||
{
|
||||
if constexpr(I >= E){
|
||||
if constexpr(std::is_same<F,NoF>::value){
|
||||
return;
|
||||
}
|
||||
else {
|
||||
return f(args...);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr(c(CSizeT<I>{})){
|
||||
return iterIfi<E,I+1>(g, f, c, args..., g(CSizeT<I>{}));
|
||||
}
|
||||
else {
|
||||
return iterIfi<E,I+1>(g, f, c, args...);
|
||||
}
|
||||
}
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
template <SizeT B, SizeT E, class G, class F, class C>
|
||||
constexpr decltype(auto) iterIf(const G& g, const F& f, const C& c)
|
||||
{
|
||||
return iterIfi<E,B>(g, f, c);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,57 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/iter.h
|
||||
@brief Static for-loops
|
||||
|
||||
Declaration of function templates that can be used to implement a static for-loop
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_iter_h__
|
||||
#define __cxz_iter_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include "types.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** @cond 0 */
|
||||
template <class G, class F, SizeT... Is>
|
||||
constexpr decltype(auto) iteri(const G& g, const F& f, Isq<Is...> is);
|
||||
/** @endcond */
|
||||
|
||||
/** static for loop
|
||||
@tparam B begin index
|
||||
@tparam E end index
|
||||
@tparam G type of expression to executed for each element
|
||||
@tparam F type of accumulating expression collecting result for all elements
|
||||
@param g expression to executed for each element
|
||||
@param f accumulating expression collecting result for all elements
|
||||
*/
|
||||
template <SizeT B, SizeT E, class G, class F>
|
||||
constexpr decltype(auto) iter(const G& g, const F& f);
|
||||
|
||||
/** @cond 0 */
|
||||
template <SizeT E, SizeT I, class G, class F, class C, typename... Args>
|
||||
constexpr decltype(auto) iterIfi(const G& g, const F& f, const C& c, const Args&... args);
|
||||
/** @endcond */
|
||||
|
||||
/** static conditional for loop
|
||||
@tparam B begin index
|
||||
@tparam E end index
|
||||
@tparam G type of expression to executed for each element
|
||||
@tparam F type of accumulating expression collecting result for all elements
|
||||
@tparam C type of condition expression
|
||||
@param g expression to executed for each element
|
||||
@param f accumulating expression collecting result for all elements
|
||||
@param c condition expression
|
||||
*/
|
||||
template <SizeT B, SizeT E, class G, class F, class C>
|
||||
constexpr decltype(auto) iterIf(const G& g, const F& f, const C& c);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,135 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/macros.h
|
||||
@brief useful macros
|
||||
|
||||
Define useful macros that are used throughout this library for convenience,
|
||||
briefnes and/or debugging.
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_macros_h__
|
||||
#define __cxz_macros_h__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifndef CHECK
|
||||
#define CHECK std::cout << __FILE__ << ": @" << __LINE__ << " in " << __func__ << std::endl;
|
||||
#endif
|
||||
#ifndef VCHECK
|
||||
#define VCHECK(a) std::cout << __FILE__ << ": @" << __LINE__ \
|
||||
<< " in " << __func__ << ": " << #a << " = " << a << std::endl;
|
||||
#endif
|
||||
|
||||
/** shortcut for defining default constructor */
|
||||
#define DEFAULT_C(__class_name__) __class_name__() = default
|
||||
|
||||
/** shortcut for defining default copy constructor */
|
||||
#define DEFAULT_COPY_C(__class_name__) __class_name__(const __class_name__& a) = default
|
||||
|
||||
/** shortcut for defining default copy assignment */
|
||||
#define DEFAULT_COPY_A(__class_name__) __class_name__& operator=(const __class_name__& a) = default
|
||||
|
||||
/** shortcut for defining default move constructor */
|
||||
#define DEFAULT_MOVE_C(__class_name__) __class_name__(__class_name__&& a) = default
|
||||
|
||||
/** shortcut for defining default move assignment */
|
||||
#define DEFAULT_MOVE_A(__class_name__) __class_name__& operator=(__class_name__&& a) = default
|
||||
|
||||
/** shortcut for defining default copy constructor and assignment */
|
||||
#define DEFAULT_COPY(__class_name__) DEFAULT_COPY_C(__class_name__); DEFAULT_COPY_A(__class_name__)
|
||||
|
||||
/** shortcut for defining default move constructor and assignment */
|
||||
#define DEFAULT_MOVE(__class_name__) DEFAULT_MOVE_C(__class_name__); DEFAULT_MOVE_A(__class_name__)
|
||||
|
||||
/** shortcut for defining default copy and move constructor and assignment */
|
||||
#define DEFAULT_MEMBERS_X(__class_name__) DEFAULT_COPY(__class_name__); DEFAULT_MOVE(__class_name__)
|
||||
|
||||
/** shortcut for defining default constructor, default copy and move constructor and assignment */
|
||||
#define DEFAULT_MEMBERS(__class_name__) DEFAULT_C(__class_name__); DEFAULT_MEMBERS_X(__class_name__)
|
||||
|
||||
/** shortcut for defining default constructor
|
||||
@param __spec__ specifier
|
||||
@param __class_name__ class name
|
||||
*/
|
||||
#define SP_DEFAULT_C(__spec__,__class_name__) __spec__ __class_name__() = default
|
||||
|
||||
/** shortcut for defining default copy constructor
|
||||
@param __spec__ specifier
|
||||
@param __class_name__ class name
|
||||
*/
|
||||
#define SP_DEFAULT_COPY_C(__spec__,__class_name__) __spec__ __class_name__(const __class_name__& a) = default
|
||||
|
||||
/** shortcut for defining default copy assignment
|
||||
@param __spec__ specifier
|
||||
@param __class_name__ class name
|
||||
*/
|
||||
#define SP_DEFAULT_COPY_A(__spec__,__class_name__) __spec__ __class_name__& operator=(const __class_name__& a) = default
|
||||
|
||||
/** shortcut for defining default move constructor
|
||||
@param __spec__ specifier
|
||||
@param __class_name__ class name
|
||||
*/
|
||||
#define SP_DEFAULT_MOVE_C(__spec__,__class_name__) __spec__ __class_name__(__class_name__&& a) = default
|
||||
|
||||
/** shortcut for defining default move assignment
|
||||
@param __spec__ specifier
|
||||
@param __class_name__ class name
|
||||
*/
|
||||
#define SP_DEFAULT_MOVE_A(__spec__,__class_name__) __spec__ __class_name__& operator=(__class_name__&& a) = default
|
||||
|
||||
/** shortcut for defining default copy constructor and assignment
|
||||
@param __spec__ specifier
|
||||
@param __class_name__ class name
|
||||
*/
|
||||
#define SP_DEFAULT_COPY(__spec__,__class_name__) SP_DEFAULT_COPY_C(__spec__,__class_name__); SP_DEFAULT_COPY_A(__spec__,__class_name__)
|
||||
|
||||
/** shortcut for defining default move constructor and assignment
|
||||
@param __spec__ specifier
|
||||
@param __class_name__ class name
|
||||
*/
|
||||
#define SP_DEFAULT_MOVE(__spec__,__class_name__) SP_DEFAULT_MOVE_C(__spec__,__class_name__); SP_DEFAULT_MOVE_A(__spec__,__class_name__)
|
||||
|
||||
/** shortcut for defining default copy and move constructor and assignment
|
||||
@param __spec__ specifier
|
||||
@param __class_name__ class name
|
||||
*/
|
||||
#define SP_DEFAULT_MEMBERS_X(__spec__,__class_name__) SP_DEFAULT_COPY(__spec__,__class_name__); SP_DEFAULT_MOVE(__spec__,__class_name__)
|
||||
|
||||
/** shortcut for defining default constructor, default copy and move constructor and assignment
|
||||
@param __spec__ specifier
|
||||
@param __class_name__ class name
|
||||
*/
|
||||
#define SP_DEFAULT_MEMBERS(__spec__,__class_name__) SP_DEFAULT_C(__spec__,__class_name__); SP_DEFAULT_MEMBERS_X(__spec__,__class_name__)
|
||||
|
||||
/** shortcut for all typedefs needed to use a class as iterator
|
||||
@param __meta_type__ meta data type
|
||||
*/
|
||||
#define INDEX_RANDOM_ACCESS_ITERATOR_DEFS(__meta_type__) typedef std::random_access_iterator_tag iterator_category; \
|
||||
typedef SizeT difference_type; \
|
||||
typedef __meta_type__ value_type; \
|
||||
typedef const __meta_type__* pointer; \
|
||||
typedef const __meta_type__& reference
|
||||
|
||||
#define CXZ_CVAL_FALSE static constexpr bool value = false
|
||||
#define CXZ_CVAL_TRUE static constexpr bool value = true
|
||||
|
||||
#define IS_SAME(a,b) std::is_same<a,b>::value
|
||||
#define IS_NOT_SAME(a,b) (not std::is_same<a,b>::value)
|
||||
|
||||
#ifdef HAVE_CEREAL
|
||||
#define SERIALIZATION_FUNCTIONS template <class Archive> void save(Archive& ar, const std::uint32_t version) const; \
|
||||
template <class Archive> void load(Archive& ar, const std::uint32_t version)
|
||||
#define SERIALIZATION_FUNCTIONS_NOPUB friend class cereal::access; \
|
||||
template <class Archive> void save(Archive& ar, const std::uint32_t version) const; \
|
||||
template <class Archive> void load(Archive& ar, const std::uint32_t version)
|
||||
#else
|
||||
#define SERIALIZATION_FUNCTIONS static const int v = 0
|
||||
#define SERIALIZATION_FUNCTIONS_NOPUB static const int v = 0
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,74 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/obj_handle.cc.h
|
||||
@brief ObjHandle function definition
|
||||
|
||||
Implementation of the member functions of template ObjHandle
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_obj_handle_cc_h__
|
||||
#define __cxz_obj_handle_cc_h__
|
||||
|
||||
#include "obj_handle.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
ObjHandle<T>::ObjHandle() {}
|
||||
|
||||
template <typename T>
|
||||
ObjHandle<T>::ObjHandle(Uptr<T>&& a) : mC(std::forward<Uptr<T>>(a)) {}
|
||||
|
||||
template <typename T>
|
||||
ObjHandle<T>::ObjHandle(const ObjHandle& a) : mC(a.mC->copy()) {}
|
||||
|
||||
template <typename T>
|
||||
ObjHandle<T>::ObjHandle(ObjHandle&& a) : mC(a.mC) {}
|
||||
|
||||
template <typename T>
|
||||
ObjHandle<T>& ObjHandle<T>::operator=(const ObjHandle& a)
|
||||
{
|
||||
mC = std::make_unique<T>(*a.mC);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ObjHandle<T>& ObjHandle<T>::operator=(ObjHandle&& a)
|
||||
{
|
||||
mC = a.mC;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& ObjHandle<T>::operator*()
|
||||
{
|
||||
return *mC;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* ObjHandle<T>::operator->()
|
||||
{
|
||||
return &*mC;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& ObjHandle<T>::operator*() const
|
||||
{
|
||||
return *mC;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* ObjHandle<T>::operator->() const
|
||||
{
|
||||
return &*mC;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,84 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/obj_handle.h
|
||||
@brief ObjHandle template declaration
|
||||
|
||||
Pointer wrapper for directly handling objects via abstract base class;
|
||||
Provides appropriate copy implementation
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_obj_handle_h__
|
||||
#define __cxz_obj_handle_h__
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
/** ****
|
||||
unique pointer wrapper
|
||||
|
||||
Allows to handle objects accessed through abstract base class pointers
|
||||
as if they were complete (non-virtual) types.
|
||||
Each type to be handled is required to have a copy() member function
|
||||
that returns a copy of itself
|
||||
|
||||
@tparam T object type
|
||||
*/
|
||||
template <typename T>
|
||||
class ObjHandle
|
||||
{
|
||||
protected:
|
||||
Uptr<T> mC; /**< pointer to the object data */
|
||||
|
||||
public:
|
||||
|
||||
/** default constructor */
|
||||
ObjHandle();
|
||||
|
||||
/** construct from unique pointer
|
||||
@param a unique pointer
|
||||
*/
|
||||
ObjHandle(Uptr<T>&& a);
|
||||
|
||||
/** copy construct
|
||||
@param a input
|
||||
*/
|
||||
ObjHandle(const ObjHandle& a);
|
||||
|
||||
/** move construct
|
||||
@param a input
|
||||
*/
|
||||
ObjHandle(ObjHandle&& a);
|
||||
|
||||
/** copy assign
|
||||
@param a input
|
||||
*/
|
||||
ObjHandle& operator=(const ObjHandle& a);
|
||||
|
||||
/** move assign
|
||||
@param a input
|
||||
*/
|
||||
ObjHandle& operator=(ObjHandle&& a);
|
||||
|
||||
/** access data */
|
||||
T& operator*();
|
||||
|
||||
/** get pointer to data */
|
||||
T* operator->();
|
||||
|
||||
/** access data (const) */
|
||||
const T& operator*() const;
|
||||
|
||||
/** get pointer to data (const) */
|
||||
const T* operator->() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,113 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/to_string.cc.h
|
||||
@brief String converter implementation
|
||||
|
||||
Implementation of functions that convert a given object/type to a string
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_to_string_cc_h__
|
||||
#define __cxz_to_string_cc_h__
|
||||
|
||||
#include "to_string.h"
|
||||
#include "iter.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
template <typename T>
|
||||
String ToString<T>::func(const T& a)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << a;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
String ToString<Vector<T>>::func(const Vector<T>& a)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "[";
|
||||
if(a.size() == 0){
|
||||
ss << "]";
|
||||
}
|
||||
else {
|
||||
auto it = a.begin();
|
||||
for(; it != a.end()-1; ++it){
|
||||
ss << toString(*it) << ",";
|
||||
}
|
||||
ss << toString(*it) << "]";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
String ToString<Arr<T,N>>::func(const Arr<T,N>& a)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "(";
|
||||
if constexpr(N == 0){
|
||||
ss << ")";
|
||||
}
|
||||
else {
|
||||
auto it = a.begin();
|
||||
for(; it != a.end()-1; ++it){
|
||||
ss << toString(*it) << ",";
|
||||
}
|
||||
ss << toString(*it) << ")";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template <typename... Ts>
|
||||
String ToString<Tuple<Ts...>>::func(const Tuple<Ts...>& t)
|
||||
{
|
||||
const String blim = "(";
|
||||
const String elim = ")";
|
||||
const String dlim = ",";
|
||||
return iter<1,sizeof...(Ts)>
|
||||
( [&](auto i) { return toString(std::get<i>(t)); },
|
||||
[&](const auto&... xs) {
|
||||
return blim + toString(std::get<0>(t)) + ( (dlim + xs) + ... ) + elim;
|
||||
} );
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
String ToString<std::pair<T,S>>::func(const std::pair<T,S>& p)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return ToString<T>::func(a);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,135 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/to_string.h
|
||||
@brief String converter declarations.
|
||||
|
||||
Declaration of functions that convert a given object/type to a string.
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_to_string_h__
|
||||
#define __cxz_to_string_h__
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** ***
|
||||
Generic cast to string
|
||||
@tparam T type to be casted
|
||||
*/
|
||||
template <typename T>
|
||||
struct ToString
|
||||
{
|
||||
/** cast to string
|
||||
@param a object to be casted
|
||||
*/
|
||||
static String func(const T& a);
|
||||
};
|
||||
|
||||
/** ***
|
||||
Specialization of ToString for strings
|
||||
*/
|
||||
template <>
|
||||
struct ToString<String>
|
||||
{
|
||||
/** cast to string
|
||||
@param a string to be casted
|
||||
*/
|
||||
static String func(const String& a);
|
||||
};
|
||||
|
||||
/** ***
|
||||
Specialization of ToString for vectors
|
||||
@tparam T vector element type
|
||||
*/
|
||||
template <typename T>
|
||||
struct ToString<Vector<T>>
|
||||
{
|
||||
/** cast to string
|
||||
@param a vector to be casted
|
||||
*/
|
||||
static String func(const Vector<T>& a);
|
||||
};
|
||||
|
||||
/** ***
|
||||
Specialization of ToString for arrays
|
||||
@tparam T array element type
|
||||
@tparam N array size
|
||||
*/
|
||||
template <typename T, SizeT N>
|
||||
struct ToString<Arr<T,N>>
|
||||
{
|
||||
/** cast to string
|
||||
@param a array to be casted
|
||||
*/
|
||||
static String func(const Arr<T,N>& a);
|
||||
};
|
||||
|
||||
/** ***
|
||||
Specialization of ToString for tuples
|
||||
@tparam Ts tuple element types
|
||||
*/
|
||||
template <typename... Ts>
|
||||
struct ToString<Tuple<Ts...>>
|
||||
{
|
||||
/** cast to string
|
||||
@param a tuple to be casted
|
||||
*/
|
||||
static String func(const Tuple<Ts...>& t);
|
||||
};
|
||||
|
||||
/** ***
|
||||
Specialization of ToString for pairs
|
||||
@tparam T first element type
|
||||
@tparam S second element type
|
||||
*/
|
||||
template <typename T, typename S>
|
||||
struct ToString<std::pair<T,S>>
|
||||
{
|
||||
/** cast to string
|
||||
@param a pair to be casted
|
||||
*/
|
||||
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
|
||||
*/
|
||||
template <>
|
||||
struct ToString<DType>
|
||||
{
|
||||
/** cast to string
|
||||
@param a DType to be casted
|
||||
*/
|
||||
static String func(const DType& a);
|
||||
};
|
||||
|
||||
/** wrapper function for ToString
|
||||
@tparam T type to be casted
|
||||
@param a object to be casted
|
||||
*/
|
||||
template <typename T>
|
||||
String toString(const T& a);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,321 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/types.h
|
||||
@brief Declaration of all library types
|
||||
|
||||
This file contains the declaration of all library types
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_types_h__
|
||||
#define __cxz_types_h__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <complex>
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
#include <numeric>
|
||||
#include <cstdint>
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/*====================+
|
||||
| standard types |
|
||||
=====================*/
|
||||
|
||||
typedef std::intptr_t PtrId;
|
||||
typedef int32_t Int;
|
||||
typedef int64_t LInt;
|
||||
typedef uint64_t SizeT;
|
||||
typedef double Double;
|
||||
typedef Double Real;
|
||||
typedef std::complex<Real> Complex;
|
||||
typedef std::string String;
|
||||
|
||||
template <typename T, size_t N>
|
||||
using Arr = std::array<T,N>;
|
||||
|
||||
template <typename T>
|
||||
using Sptr = std::shared_ptr<T>;
|
||||
|
||||
template <typename T>
|
||||
using Wptr = std::weak_ptr<T>;
|
||||
|
||||
template <typename T>
|
||||
using Uptr = std::unique_ptr<T>;
|
||||
|
||||
template <typename T, typename U>
|
||||
using Pair = std::pair<T,U>;
|
||||
|
||||
template <typename... T>
|
||||
using Tuple = std::tuple<T...>;
|
||||
|
||||
template <SizeT I, typename... T>
|
||||
using TupleElem = std::tuple_element<I,Tuple<T...>>;
|
||||
|
||||
template <typename T>
|
||||
using RemoveRef = typename std::remove_reference<T>::type;
|
||||
|
||||
template <typename K, typename V>
|
||||
using Map = std::map<K,V>;
|
||||
|
||||
typedef std::type_info TypeInfo;
|
||||
|
||||
template <SizeT... Is>
|
||||
using Isq = std::index_sequence<Is...>;
|
||||
// cxz helper functions/classes: -> isq.h
|
||||
|
||||
template <class... T>
|
||||
using Isqf = std::index_sequence_for<T...>;
|
||||
|
||||
template <SizeT N>
|
||||
using CSizeT = std::integral_constant<SizeT,N>;
|
||||
|
||||
/*===================+
|
||||
| library types |
|
||||
+===================*/
|
||||
|
||||
/*
|
||||
Naming Prefixes:
|
||||
D = Y = Dynamic
|
||||
V = X = Virtual
|
||||
S = Static
|
||||
P = Partial = Sub
|
||||
C = Classic
|
||||
M = Multi (Index,Ranges) or !const (Container)
|
||||
U = One(=Uni) dimensional
|
||||
N = None = Null
|
||||
E = Extension (SSE,AVX,etc dof)
|
||||
T = Thread
|
||||
R = Rank
|
||||
A = (const) Array
|
||||
B = (mutable) Array
|
||||
F = Functional, Map,...
|
||||
*/
|
||||
|
||||
// default template parameter
|
||||
class None {};
|
||||
|
||||
// definition: base/dtype.h
|
||||
class DType;
|
||||
|
||||
// definition: base/obj_handle.h
|
||||
template <typename T>
|
||||
class ObjHandle;
|
||||
|
||||
// definition: memory/allocator.h
|
||||
template <typename T>
|
||||
class Allocator;
|
||||
|
||||
// definition: xpr/vpos_type.h
|
||||
class VPosBase;
|
||||
|
||||
// definition: xpr/vpos_type.h
|
||||
template <class PosT>
|
||||
class VPos;
|
||||
|
||||
// definition: xpr/vpos_type.h
|
||||
template <class PosT>
|
||||
class VPosRef;
|
||||
|
||||
// definition: xpr/pos_type.h
|
||||
class UPos;
|
||||
|
||||
// definition: xpr/pos_type.h
|
||||
template <SizeT N>
|
||||
class SPos;
|
||||
|
||||
// definition: xpr/pos_type.h
|
||||
class FPos;
|
||||
|
||||
// definition: xpr/pos_type.h
|
||||
template <SizeT N, SizeT... Ms>
|
||||
class SFPos;
|
||||
|
||||
// definition: xpr/pos_type.h
|
||||
class DPos;
|
||||
|
||||
// definition: xpr/pos_type.h
|
||||
class DPosRef;
|
||||
|
||||
// definition: xpr/pos_type.h
|
||||
template <class PosT1, class PosT2>
|
||||
class MPos;
|
||||
|
||||
// definition: ranges/range_base.h
|
||||
class RangeBase;
|
||||
|
||||
typedef Sptr<RangeBase> RangePtr;
|
||||
|
||||
// definition: ranges/index_base.h
|
||||
template <class I, typename MetaType>
|
||||
class IndexInterface;
|
||||
|
||||
template <class I, typename MetaType>
|
||||
using IndexPtr = Sptr<IndexInterface<I,MetaType>>;
|
||||
|
||||
// definition: ranges/nrange.h
|
||||
class NRange; // null-range (range over none)
|
||||
|
||||
// definition: ranges/nrange.h
|
||||
class NIndex;
|
||||
|
||||
// definition: ranges/urange.h
|
||||
template <typename Meta>
|
||||
class URange; // generic simple range (uni-dimensional)
|
||||
|
||||
// definition: ranges/urange.h
|
||||
template <typename Meta>
|
||||
class UIndex;
|
||||
|
||||
// definition: ranges/prange.h
|
||||
template <class Range>
|
||||
class PRange;
|
||||
|
||||
// definition: ranges/prange.h
|
||||
template <class Index>
|
||||
class PIndex;
|
||||
|
||||
// definition: ranges/crange.h
|
||||
class CRange; // classic range, trivial meta data
|
||||
|
||||
// definition: ranges/crange.h
|
||||
class CIndex;
|
||||
|
||||
// definition: ranges/srange.h
|
||||
template <typename Meta, SizeT S>
|
||||
class SRange; // generic static size range
|
||||
|
||||
// definition: ranges/srange.h
|
||||
template <typename Meta, SizeT S>
|
||||
class SIndex;
|
||||
|
||||
// definition: ranges/mrange.h
|
||||
template <class... Ranges>
|
||||
class MRange; // multi range
|
||||
|
||||
// definition: ranges/mrange.h
|
||||
template <class BlockType, class... Indices>
|
||||
class GMIndex;
|
||||
|
||||
template <class... Indices>
|
||||
using MIndex = GMIndex<None,Indices...>;
|
||||
|
||||
// definition: ranges/xindex.h
|
||||
class XIndexBase; // dynamic index wrapper
|
||||
|
||||
typedef Sptr<XIndexBase> XIndexPtr;
|
||||
|
||||
// definition: ranges/dindex.h
|
||||
class DIndex;
|
||||
|
||||
// definition: ranges/yrange.h
|
||||
class YRange; // dynamic multi range
|
||||
|
||||
// definition: ranges/yrange.h
|
||||
class YIndex;
|
||||
|
||||
typedef Sptr<YIndex> YIndexPtr;
|
||||
|
||||
// definition: ranges/pindex.h
|
||||
template <class Index>
|
||||
class PIndex; // partial index (index over sub-ranges and permutations)
|
||||
|
||||
// there should be also a static analogue
|
||||
|
||||
// definition: ranges/lindex.h
|
||||
template <class Index, SizeT L>
|
||||
class LIndex;
|
||||
|
||||
// definition: ranges/index_pack.h
|
||||
template <class... Indices>
|
||||
class SPack;
|
||||
|
||||
// definition: ranges/index_pack.h
|
||||
class DPack;
|
||||
|
||||
// definition: ranges/index_format.h
|
||||
template <SizeT N>
|
||||
class MFormat;
|
||||
|
||||
// definition: ranges/index_format.h
|
||||
template <class... PosT>
|
||||
class GMFormat;
|
||||
|
||||
// definition: ranges/index_format.h
|
||||
class YFormat;
|
||||
|
||||
// definition: array/array_base.h
|
||||
template <typename T>
|
||||
class CArrayBase;
|
||||
|
||||
// definition: array/array_base.h
|
||||
template <typename T>
|
||||
class ArrayBase;
|
||||
|
||||
// definition: array/array.h
|
||||
template <typename T>
|
||||
class MArray;
|
||||
|
||||
// definition: array/slice.h
|
||||
template <typename T>
|
||||
class CSlice;
|
||||
|
||||
// definition: array/slice.h
|
||||
template <typename T>
|
||||
class Slice;
|
||||
|
||||
// definition: operation/op_types.h
|
||||
template <class OpT>
|
||||
class COpInterface;
|
||||
|
||||
// definition: operation/op_types.h
|
||||
template <class OpT>
|
||||
class OpInterface;
|
||||
|
||||
// definition: operation/op_types.h
|
||||
template <typename T, class IndexT>
|
||||
class COpRoot;
|
||||
|
||||
// definition: operation/op_types.h
|
||||
template <typename T, class IndexT>
|
||||
class OpCont;
|
||||
|
||||
// definition: operation/op_types.h
|
||||
template <typename T, class IndexT>
|
||||
class OpRoot;
|
||||
|
||||
// definition: operation/op_types.h
|
||||
template <class F, class... Ops>
|
||||
class Operation;
|
||||
|
||||
// definition: operation/op_types.h
|
||||
template <class CXpr>
|
||||
class Contraction;
|
||||
|
||||
/*===================+
|
||||
| derived types |
|
||||
+===================*/
|
||||
|
||||
template <typename T>
|
||||
using Vector = std::vector<T,Allocator<T>>;
|
||||
|
||||
template <typename T, SizeT N, bool Static>
|
||||
struct Container
|
||||
{ typedef Vector<T> type; };
|
||||
|
||||
template <typename T, SizeT N>
|
||||
struct Container<T,N,true>
|
||||
{ typedef Arr<T,N> type; };
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,147 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/utils.h
|
||||
@brief utilities
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_utils_h__
|
||||
#define __cxz_utils_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include "types.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
template <typename T, SizeT N>
|
||||
Vector<T> toVec(const Arr<T,N>& a)
|
||||
{
|
||||
return iter<0,N>( [&](auto i) { return std::get<i>(a); },
|
||||
[](const auto&... e) { return Vector<T> { e... }; } );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector<T> toVec(const Vector<T>& a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector<T> toVec(const T& a)
|
||||
{
|
||||
return Vector<T> { a };
|
||||
}
|
||||
|
||||
template <typename T, SizeT N1, SizeT N2>
|
||||
constexpr Arr<T,N1+N2> cat2(const Arr<T,N1>& a1, const Arr<T,N2>& a2)
|
||||
{
|
||||
return iter<0,N1+N2>
|
||||
( [&](auto i) { if constexpr(i < N1) { return std::get<i>(a1); } else { return std::get<i-N1>(a2); } },
|
||||
[](const auto&... e) { return Arr<T,N1+N2> { e... }; } );
|
||||
}
|
||||
|
||||
template <typename T, SizeT N1>
|
||||
constexpr Arr<T,N1+1> cat2(const Arr<T,N1>& a1, const T& a2)
|
||||
{
|
||||
return iter<0,N1>
|
||||
( [&](auto i) { return std::get<i>(a1); },
|
||||
[&](const auto&... e) { return Arr<T,N1+1> { e..., a2 }; } );
|
||||
}
|
||||
|
||||
template <typename T, SizeT N1>
|
||||
constexpr Arr<T,N1+1> cat2(const T& a1, const Arr<T,N1>& a2)
|
||||
{
|
||||
return iter<0,N1>
|
||||
( [&](auto i) { return std::get<i>(a2); },
|
||||
[&](const auto&... e) { return Arr<T,N1+1> { a1, e... }; } );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr Arr<T,2> cat2(const T& a1, const T& a2)
|
||||
{
|
||||
return Arr<T,2> { a1, a2 };
|
||||
}
|
||||
|
||||
template <typename T, SizeT N2>
|
||||
Vector<T> cat2(const Vector<T>& a1, const Arr<T,N2>& a2)
|
||||
{
|
||||
Vector<T> o(a1.size()+N2);
|
||||
std::copy(a1.begin(), a1.end(), o.begin());
|
||||
std::copy(a2.begin(), a2.end(), o.begin()+a1.size());
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T, SizeT N1>
|
||||
Vector<T> cat2(const Arr<T,N1>& a1, const Vector<T>& a2)
|
||||
{
|
||||
Vector<T> o(N1+a2.size());
|
||||
std::copy(a1.begin(), a1.end(), o.begin());
|
||||
std::copy(a2.begin(), a2.end(), o.begin()+N1);
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector<T> cat2(const Vector<T>& a1, const Vector<T>& a2)
|
||||
{
|
||||
Vector<T> o(a1.size()+a2.size());
|
||||
std::copy(a1.begin(), a1.end(), o.begin());
|
||||
std::copy(a2.begin(), a2.end(), o.begin()+a1.size());
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector<T> cat2(const Vector<T>& a1, const T& a2)
|
||||
{
|
||||
Vector<T> o(a1);
|
||||
o.push_back(a2);
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T, SizeT N1>
|
||||
Vector<T> cat2(const T& a1, const Vector<T>& a2)
|
||||
{
|
||||
Vector<T> o { a1 };
|
||||
o.insert(o.end(), a2.begin(), a2.end());
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename... Ts>
|
||||
decltype(auto) concat(const T1& a1, const T2& a2, const Ts&... as)
|
||||
{
|
||||
if constexpr(sizeof...(Ts) != 0){
|
||||
return cat2(a1, concat(a2, as...));
|
||||
}
|
||||
else {
|
||||
return cat2(a1, a2);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, SizeT N>
|
||||
constexpr Arr<T,N> mul(const Arr<T,N>& a, const T& b)
|
||||
{
|
||||
return iter<0,N>( [&](auto i) { return std::get<i>(a) * b; },
|
||||
[](const auto&... e) { return Arr<T,N> { e... }; } );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector<T> mul(const Vector<T>& a, const T& b)
|
||||
{
|
||||
Vector<T> o(a.size());
|
||||
std::transform(a.begin(), a.end(), o.begin(), [&](const auto& x) { return x*b; } );
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr T mul(const T& a, const T& b)
|
||||
{
|
||||
return a*b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,87 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/base/uuid.h
|
||||
@brief cnorxz uuid declaration.
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_uuid_h__
|
||||
#define __cxz_uuid_h__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <functional>
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** ***
|
||||
uuid
|
||||
*/
|
||||
struct Uuid
|
||||
{
|
||||
uint64_t i1; /**< first 8 bytes */
|
||||
uint64_t i2; /**< second 8 bytes */
|
||||
};
|
||||
|
||||
/** create new uuid */
|
||||
Uuid mkUuid();
|
||||
|
||||
/** operator equal to
|
||||
@param a left hand side
|
||||
@param b right hand side
|
||||
*/
|
||||
inline bool operator==(const Uuid& a, const Uuid& b)
|
||||
{
|
||||
return a.i1 == b.i1 and a.i2 == b.i2;
|
||||
}
|
||||
|
||||
/** operator not equal to
|
||||
@param a left hand side
|
||||
@param b right hand side
|
||||
*/
|
||||
inline bool operator!=(const Uuid& a, const Uuid& b)
|
||||
{
|
||||
return a.i1 != b.i1 or a.i2 != b.i2;
|
||||
}
|
||||
|
||||
/** operator less than
|
||||
@param a left hand side
|
||||
@param b right hand side
|
||||
*/
|
||||
inline bool operator<(const Uuid& a, const Uuid& b)
|
||||
{
|
||||
return (a.i1 == b.i1) ? a.i2 < b.i2 : a.i1 < b.i1;
|
||||
}
|
||||
|
||||
/** operator greater than
|
||||
@param a left hand side
|
||||
@param b right hand side
|
||||
*/
|
||||
inline bool operator>(const Uuid& a, const Uuid& b)
|
||||
{
|
||||
return (a.i1 == b.i1) ? a.i2 > b.i2 : a.i1 > b.i1;
|
||||
}
|
||||
|
||||
/** operator less or equal
|
||||
@param a left hand side
|
||||
@param b right hand side
|
||||
*/
|
||||
inline bool operator<=(const Uuid& a, const Uuid& b)
|
||||
{
|
||||
return not( (a.i1 == b.i1) ? a.i2 > b.i2 : a.i1 > b.i1 );
|
||||
}
|
||||
|
||||
/** operator greater or equal
|
||||
@param a left hand side
|
||||
@param b right hand side
|
||||
*/
|
||||
inline bool operator>=(const Uuid& a, const Uuid& b)
|
||||
{
|
||||
return not( (a.i1 == b.i1) ? a.i2 < b.i2 : a.i1 < b.i1 );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
39
src/include/base_def.h
Normal file
39
src/include/base_def.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
#ifndef __base_def_h__
|
||||
#define __base_def_h__
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#define DEBUG_MODE_X
|
||||
|
||||
#ifdef DEBUG_MODE_X
|
||||
|
||||
#include <iostream>
|
||||
#ifndef CHECK
|
||||
#define CHECK std::cout << __FILE__ << ": @" << __LINE__ << " in " << __func__ << std::endl;
|
||||
#endif
|
||||
#ifndef VCHECK
|
||||
#define VCHECK(a) std::cout << __FILE__ << ": @" << __LINE__ \
|
||||
<< " in " << __func__ << ": " << #a << " = " << a << std::endl;
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define CHECK
|
||||
#define VCHECK(a)
|
||||
|
||||
#endif
|
||||
|
||||
#define DEFAULT_MEMBERS(__class_name__) __class_name__() = default; \
|
||||
__class_name__(const __class_name__& in) = default; \
|
||||
__class_name__& operator=(const __class_name__& in) = default; \
|
||||
__class_name__(__class_name__&& in) = default; \
|
||||
__class_name__& operator=(__class_name__&& in) = default
|
||||
|
||||
#define DEFAULT_MEMBERS_X(__class_name__) __class_name__(const __class_name__& in) = default; \
|
||||
__class_name__& operator=(const __class_name__& in) = default; \
|
||||
__class_name__(__class_name__&& in) = default; \
|
||||
__class_name__& operator=(__class_name__&& in) = default
|
||||
|
||||
|
||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/cnorxz.cc.h
|
||||
@brief cnorxz main template header
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#include "base/base.cc.h"
|
||||
#include "memory/memory.cc.h"
|
||||
#include "ranges/ranges.cc.h"
|
||||
#include "array/array.cc.h"
|
||||
#include "operation/operation.cc.h"
|
|
@ -1,23 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/cnorxz.h
|
||||
@brief cnorxz main header
|
||||
|
||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_cnorxz_h__
|
||||
#define __cxz_cnorxz_h__
|
||||
|
||||
#include "base/base.h"
|
||||
#include "memory/memory.h"
|
||||
#include "ranges/ranges.h"
|
||||
#include "array/array.h"
|
||||
#include "operation/operation.h"
|
||||
|
||||
#include "cnorxz.cc.h"
|
||||
|
||||
#endif
|
122
src/include/conversions.h
Normal file
122
src/include/conversions.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
|
||||
#ifndef __ma_conversions_h__
|
||||
#define __ma_conversions_h__
|
||||
|
||||
#include "multi_array.h"
|
||||
#include "slice.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
namespace ConversionSizes
|
||||
{
|
||||
template <size_t N>
|
||||
struct OrigSize
|
||||
{
|
||||
template <typename C, typename T>
|
||||
struct FromTo
|
||||
{
|
||||
static void check() { static_assert( not N % (sizeof(T) / sizeof(C)), "conversion does not fit" ); }
|
||||
static constexpr size_t SIZE = N * sizeof(T) / sizeof(C);
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OrigSize<MUI>
|
||||
{
|
||||
template <typename C, typename T>
|
||||
struct FromTo
|
||||
{
|
||||
static void check() {}
|
||||
static constexpr size_t SIZE = MUI;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename C, typename T, size_t N>
|
||||
using SC = typename ConversionSizes::OrigSize<N>::template FromTo<C,T>;
|
||||
|
||||
template <typename C, typename T, class Range>
|
||||
using SCR = SC<C,T,Range::SIZE>;
|
||||
|
||||
template <typename C, typename T, class Range>
|
||||
using SCRR = GenSingleRange<typename Range::MetaType,SpaceType::NONE,SCR<C,T,Range>::SIZE>;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
struct SubTuple
|
||||
{
|
||||
template <class RTP, class... Ranges>
|
||||
static inline auto mk(const RTP& rtp, const Ranges&... rs)
|
||||
-> decltype(SubTuple<N-1>::mk(rtp, std::get<N>(rtp), rs...))
|
||||
{
|
||||
return SubTuple<N-1>::mk(rtp, std::get<N>(rtp), rs...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct SubTuple<0>
|
||||
{
|
||||
template <class RTP, class... Ranges>
|
||||
static inline auto mk(const RTP& rtp, const Ranges&... rs)
|
||||
-> decltype(std::make_tuple(std::get<0>(rtp), rs...))
|
||||
{
|
||||
return std::make_tuple(std::get<0>(rtp), rs...);
|
||||
}
|
||||
};
|
||||
|
||||
template <class... Ranges>
|
||||
using LastR = typename std::tuple_element<sizeof...(Ranges)-1,std::tuple<Ranges...>>::type;
|
||||
|
||||
template <typename C, typename T, class... Ranges>
|
||||
auto rtcast(const std::tuple<std::shared_ptr<Ranges>...>& rtp)
|
||||
-> decltype(std::tuple_cat(SubTuple<sizeof...(Ranges)-2>::mk(rtp),
|
||||
std::make_tuple( std::dynamic_pointer_cast<SCRR<C,T,LastR<Ranges...>>>
|
||||
( SCRR<C,T,LastR<Ranges...>>::factory().create() ) ) ))
|
||||
{
|
||||
return std::tuple_cat(SubTuple<sizeof...(Ranges)-2>::mk(rtp),
|
||||
std::make_tuple( std::dynamic_pointer_cast<SCRR<C,T,LastR<Ranges...>>>
|
||||
( SCRR<C,T,LastR<Ranges...>>::factory().create() ) ) );
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
inline Slice<T,Ranges...> rangeTpToSlice( const std::tuple<std::shared_ptr<Ranges>...>& rtp, T* data )
|
||||
{
|
||||
return Slice<T,Ranges...>(rtp, data);
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
inline ConstSlice<T,Ranges...> rangeTpToSlice( const std::tuple<std::shared_ptr<Ranges>...>& rtp, const T* data )
|
||||
{
|
||||
return ConstSlice<T,Ranges...>(rtp, data);
|
||||
}
|
||||
|
||||
template <typename C, typename T, class... Ranges>
|
||||
auto tcast(MultiArray<T,Ranges...>& ma)
|
||||
-> decltype(rangeTpToSlice
|
||||
( rtcast<C,T>( ma.range()->space() ),
|
||||
reinterpret_cast<C*>( ma.data() ) ))
|
||||
{
|
||||
// VCHECK(reinterpret_cast<std::intptr_t>(ma.data()) % 32);
|
||||
//VCHECK(reinterpret_cast<std::intptr_t>(reinterpret_cast<C*>(ma.data())) % 32);
|
||||
return rangeTpToSlice
|
||||
( rtcast<C,T>( ma.range()->space() ),
|
||||
reinterpret_cast<C*>( ma.data() ) );
|
||||
}
|
||||
|
||||
template <typename C, typename T, class... Ranges>
|
||||
auto tcast(const MultiArray<T,Ranges...>& ma)
|
||||
-> decltype(rangeTpToSlice
|
||||
( rtcast<C,T>( ma.range()->space() ),
|
||||
reinterpret_cast<const C*>( ma.data() ) ))
|
||||
{
|
||||
//VCHECK(reinterpret_cast<std::intptr_t>(ma.data()) % 32);
|
||||
//VCHECK(reinterpret_cast<std::intptr_t>(reinterpret_cast<C*>(ma.data())) % 32);
|
||||
return rangeTpToSlice
|
||||
( rtcast<C,T>( ma.range()->space() ),
|
||||
reinterpret_cast<const C*>( ma.data() ) );
|
||||
}
|
||||
}
|
||||
#endif
|
198
src/include/dynamic_operation.cc.h
Normal file
198
src/include/dynamic_operation.cc.h
Normal file
|
@ -0,0 +1,198 @@
|
|||
|
||||
#include "dynamic_operation.h"
|
||||
#include "helper_tools.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
template <typename T, class Operation>
|
||||
T DynamicOperation<T,Operation>::get(const DExtT& pos) const
|
||||
{
|
||||
return mOp.get(pos.expl<ET>());
|
||||
}
|
||||
|
||||
template <typename T, class Operation>
|
||||
DynamicOperationBase<T>& DynamicOperation<T,Operation>::set(const DExtT& pos)
|
||||
{
|
||||
mOp.set(pos.expl<ET>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class Operation>
|
||||
DExtT DynamicOperation<T,Operation>::rootSteps(std::intptr_t iPtrNum) const
|
||||
{
|
||||
return DExtT(mkDExt(mkExtT(mOp.rootSteps(iPtrNum))),None(0));
|
||||
}
|
||||
|
||||
template <typename T, class Operation>
|
||||
DynamicExpression DynamicOperation<T,Operation>::loop(const DynamicExpression& exp) const
|
||||
{
|
||||
return mOp.loop(exp);
|
||||
}
|
||||
|
||||
template <typename T, class Operation>
|
||||
const T* DynamicOperation<T,Operation>::data() const
|
||||
{
|
||||
return mOp.data();
|
||||
}
|
||||
|
||||
template <typename T, class Operation>
|
||||
std::shared_ptr<DynamicOperationBase<T>> DynamicOperation<T,Operation>::deepCopy() const
|
||||
{
|
||||
return std::make_shared<DynamicOperation<T,Operation>>(*this);
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(const DynamicOuterOp& in) :
|
||||
mThreadId(omp_get_thread_num()), mOp(in.mOp),
|
||||
mIndices(in.mIndices),
|
||||
mMa((mThreadId != in.mThreadId) ? std::make_shared<MultiArray<T,Ranges...>>(*in.mMa) : in.mMa),
|
||||
mProto((mThreadId != in.mThreadId) ? OperationRoot<T,Ranges...>(*mMa,mIndices) : in.mProto),
|
||||
mL((mThreadId != in.mThreadId) ?
|
||||
mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
|
||||
std::make_tuple(mMa),
|
||||
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
|
||||
std::array<size_t,1>({1}), std::array<size_t,1>({0})) :
|
||||
in.mL)
|
||||
|
||||
{*mMa = 0;}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(DynamicOuterOp&& in) :
|
||||
mThreadId(omp_get_thread_num()), mOp(in.mOp),
|
||||
mIndices(in.mIndices),
|
||||
mMa((mThreadId != in.mThreadId) ? std::make_shared<MultiArray<T,Ranges...>>(*in.mMa) : in.mMa),
|
||||
mProto((mThreadId != in.mThreadId) ? OperationRoot<T,Ranges...>(*mMa,mIndices) : in.mProto),
|
||||
mL((mThreadId != in.mThreadId) ?
|
||||
mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
|
||||
std::make_tuple(mMa),
|
||||
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
|
||||
std::array<size_t,1>({1}), std::array<size_t,1>({0})) :
|
||||
in.mL)
|
||||
|
||||
{*mMa = 0;}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
DynamicOuterOp<T,Operation,Ranges...>&
|
||||
DynamicOuterOp<T,Operation,Ranges...>::operator=(const DynamicOuterOp& in)
|
||||
{
|
||||
mThreadId = omp_get_thread_num();
|
||||
mOp = in.mOp;
|
||||
mIndices = in.mIndices;
|
||||
if(mThreadId != in.mThreadId){
|
||||
mMa = std::make_shared<MultiArray<T,Ranges...>>(in.mMa);
|
||||
mProto = OperationRoot<T,Ranges...>(*mMa,mIndices);
|
||||
mL = mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
|
||||
std::make_tuple(mMa),
|
||||
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
|
||||
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
|
||||
}
|
||||
else {
|
||||
mMa = in.mMa;
|
||||
mProto = in.mProto;
|
||||
mL = in.mL;
|
||||
}
|
||||
*mMa = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
DynamicOuterOp<T,Operation,Ranges...>&
|
||||
DynamicOuterOp<T,Operation,Ranges...>::operator=(DynamicOuterOp&& in)
|
||||
{
|
||||
mThreadId = omp_get_thread_num();
|
||||
mOp = in.mOp;
|
||||
mIndices = in.mIndices;
|
||||
if(mThreadId != in.mThreadId){
|
||||
mMa = std::make_shared<MultiArray<T,Ranges...>>(in.mMa);
|
||||
mProto = OperationRoot<T,Ranges...>(*mMa,mIndices);
|
||||
mL = mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
|
||||
std::make_tuple(mMa),
|
||||
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
|
||||
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
|
||||
}
|
||||
else {
|
||||
mMa = in.mMa;
|
||||
mProto = in.mProto;
|
||||
mL = in.mL;
|
||||
}
|
||||
*mMa = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(const Operation& op,
|
||||
const std::shared_ptr<typename Ranges::IndexType>&... inds)
|
||||
: mThreadId(omp_get_thread_num()), mOp(op),
|
||||
mIndices(inds...),
|
||||
mMa(std::make_shared<MultiArray<T,Ranges...>>(mkArray<T>(inds->range()...))),
|
||||
mProto(OperationRoot<T,Ranges...>(*mMa,inds...)),
|
||||
mL(std::make_tuple(*mProto.mOp,mOp), std::make_tuple(inds...),
|
||||
std::make_tuple(mMa), std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(inds...) )),
|
||||
std::array<size_t,1>({1}), std::array<size_t,1>({0}))
|
||||
{}
|
||||
|
||||
/*
|
||||
DynamicOuterOp(const std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<typename Operatrion::value_type,Ranges...>>>>& dyn,
|
||||
const Operation& op, const std::shared_ptr<Indices>&... inds )
|
||||
: mThreadId(omp_get_thread_num()),
|
||||
//mDyn(dyn),
|
||||
mOp(op), mIndices(inds...),
|
||||
mMa(std::make_shared<MultiArray<T,Ranges...>>(mkArray<T>(inds->range()...))),
|
||||
mProto(OperationRoot<T,Ranges...>(*mMa,inds...)),
|
||||
mL(std::make_tuple(*mProto.mOp,mOp), std::make_tuple(inds...),
|
||||
std::make_tuple(mMa), std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(inds...) )),
|
||||
std::array<size_t,1>({1}), std::array<size_t,1>({0}))
|
||||
{}
|
||||
*/
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
OpH<OperationRoot<T,Ranges...>> DynamicOuterOp<T,Operation,Ranges...>::get(const DExtT& pos) const
|
||||
{
|
||||
//if(mPrev) mPrev.get(pos.expl<ET>());
|
||||
mL(0,pos.expl<ET>());
|
||||
return mProto; // empty
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>&
|
||||
DynamicOuterOp<T,Operation,Ranges...>::set(const DExtT& pos)
|
||||
{
|
||||
mOp.set(pos.expl<ET>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
DExtT DynamicOuterOp<T,Operation,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
||||
{
|
||||
return DExtT(mkDExt(mkExtT(mL.rootSteps(iPtrNum))),None(0));
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
DynamicExpression DynamicOuterOp<T,Operation,Ranges...>::loop(const DynamicExpression& exp) const
|
||||
{
|
||||
return mOp.loop(exp); // ???!!
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
const OpH<OperationRoot<T,Ranges...>>* DynamicOuterOp<T,Operation,Ranges...>::data() const
|
||||
{
|
||||
return &mProto;
|
||||
}
|
||||
/*
|
||||
template <class Op1, class Op2>
|
||||
template <class ET>
|
||||
inline T TwoOp<Op1,Op2>::get(const ET& pos) const
|
||||
{
|
||||
return mOp2.get(pos);
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>>
|
||||
DynamicOuterOp<T,Operation,Ranges...>::deepCopy() const
|
||||
{
|
||||
return std::make_shared<DynamicOuterOp<T,Operation,Ranges...>>(*this);
|
||||
}
|
||||
|
||||
} // namespace MultiArrayTools
|
202
src/include/dynamic_operation.h
Normal file
202
src/include/dynamic_operation.h
Normal file
|
@ -0,0 +1,202 @@
|
|||
|
||||
#ifndef __dynamic_operation_h__
|
||||
#define __dynamic_operation_h__
|
||||
|
||||
#include "base_def.h"
|
||||
#include "multi_array_operation.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
class DynamicOperationBase : public OperationTemplate<T,DynamicOperationBase<T>>
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef OperationBase<T,DynamicOperationBase<T>> OT;
|
||||
|
||||
static constexpr size_t SIZE = 1;
|
||||
static constexpr bool CONT = true;
|
||||
|
||||
DynamicOperationBase() = default;
|
||||
DynamicOperationBase(const DynamicOperationBase& in) = default;
|
||||
DynamicOperationBase(DynamicOperationBase&& in) = default;
|
||||
DynamicOperationBase& operator=(const DynamicOperationBase& in) = default;
|
||||
DynamicOperationBase& operator=(DynamicOperationBase&& in) = default;
|
||||
|
||||
virtual T get(const DExtT& pos) const = 0;
|
||||
virtual DynamicOperationBase& set(const DExtT& pos) = 0;
|
||||
virtual DExtT rootSteps(std::intptr_t iPtrNum = 0) const = 0;
|
||||
virtual DynamicExpression loop(const DynamicExpression& exp) const = 0;
|
||||
virtual const T* data() const = 0;
|
||||
virtual std::shared_ptr<DynamicOperationBase<T>> deepCopy() const = 0;
|
||||
|
||||
};
|
||||
|
||||
template <typename T, class Operation>
|
||||
class DynamicOperation : public DynamicOperationBase<T>
|
||||
{
|
||||
private:
|
||||
Operation mOp;
|
||||
public:
|
||||
typedef decltype(mOp.rootSteps()) ET;
|
||||
//typedef decltype(std::declval<Operation>().rootSteps()) ET;
|
||||
|
||||
DynamicOperation() = default;
|
||||
DynamicOperation(const DynamicOperation& in) = default;
|
||||
DynamicOperation(DynamicOperation&& in) = default;
|
||||
DynamicOperation& operator=(const DynamicOperation& in) = default;
|
||||
DynamicOperation& operator=(DynamicOperation&& in) = default;
|
||||
|
||||
DynamicOperation(const Operation& op) : mOp(op) {}
|
||||
|
||||
virtual T get(const DExtT& pos) const override final;
|
||||
virtual DynamicOperationBase<T>& set(const DExtT& pos) override final;
|
||||
virtual DExtT rootSteps(std::intptr_t iPtrNum = 0) const override final;
|
||||
virtual DynamicExpression loop(const DynamicExpression& exp) const override final;
|
||||
virtual const T* data() const override final;
|
||||
virtual std::shared_ptr<DynamicOperationBase<T>> deepCopy() const override final;
|
||||
};
|
||||
|
||||
template <class Op>
|
||||
struct OpH
|
||||
{
|
||||
std::shared_ptr<Op> mOp;
|
||||
OpH(const Op& op) : mOp(std::make_shared<Op>(op)) {}
|
||||
|
||||
// overload all operations here ...
|
||||
};
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
class DynamicOuterOp : public DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>
|
||||
{
|
||||
private:
|
||||
size_t mThreadId;
|
||||
//std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>> mDyn;
|
||||
Operation mOp;
|
||||
//OperationRoot<T,Ranges...> mProto;
|
||||
std::tuple<std::shared_ptr<typename Ranges::IndexType>...> mIndices;
|
||||
std::shared_ptr<MultiArray<T,Ranges...>> mMa;
|
||||
OpH<OperationRoot<T,Ranges...>> mProto;
|
||||
|
||||
|
||||
typedef ILoop<std::tuple<OperationRoot<T,Ranges...>,Operation>,
|
||||
std::tuple<std::shared_ptr<typename Ranges::IndexType>...>,
|
||||
std::tuple<std::shared_ptr<MultiArray<T,Ranges...>>>,
|
||||
std::tuple<decltype(mProto.mOp->assign( mOp, mkMIndex(std::shared_ptr<typename Ranges::IndexType>()...) ))>> LoopT;
|
||||
|
||||
|
||||
|
||||
mutable LoopT mL;
|
||||
|
||||
public:
|
||||
typedef decltype(mL.rootSteps()) ET;
|
||||
//typedef decltype(std::declval<Operation>().rootSteps()) ET;
|
||||
|
||||
DynamicOuterOp() : mThreadId(omp_get_thread_num()) {}
|
||||
DynamicOuterOp(const DynamicOuterOp& in);
|
||||
DynamicOuterOp(DynamicOuterOp&& in);
|
||||
DynamicOuterOp& operator=(const DynamicOuterOp& in);
|
||||
DynamicOuterOp& operator=(DynamicOuterOp&& in);
|
||||
|
||||
DynamicOuterOp(const Operation& op, const std::shared_ptr<typename Ranges::IndexType>&... inds);
|
||||
/*
|
||||
DynamicOuterOp(const std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<typename Operatrion::value_type,Ranges...>>>>& dyn,
|
||||
const Operation& op, const std::shared_ptr<Indices>&... inds );
|
||||
*/
|
||||
virtual OpH<OperationRoot<T,Ranges...>> get(const DExtT& pos) const override final;
|
||||
virtual DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>& set(const DExtT& pos) override final;
|
||||
virtual DExtT rootSteps(std::intptr_t iPtrNum = 0) const override final;
|
||||
virtual DynamicExpression loop(const DynamicExpression& exp) const override final;
|
||||
virtual const OpH<OperationRoot<T,Ranges...>>* data() const override final;
|
||||
virtual std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>> deepCopy() const override final;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class DynamicO : public OperationTemplate<T,DynamicO<T>>
|
||||
{
|
||||
private:
|
||||
// NOT THREAD SAFE!!!
|
||||
std::shared_ptr<DynamicOperationBase<T>> mOp;
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef OperationBase<T,DynamicO<T>> OT;
|
||||
|
||||
static constexpr size_t SIZE = 1;
|
||||
static constexpr bool CONT = true;
|
||||
|
||||
DynamicO() = default;
|
||||
DynamicO(const DynamicO& in) : mOp(in.mOp ? in.mOp->deepCopy() : nullptr) {}
|
||||
DynamicO(DynamicO&& in) : mOp(in.mOp ? in.mOp->deepCopy() : nullptr) {}
|
||||
DynamicO& operator=(const DynamicO& in)
|
||||
{ mOp = in.mOp ? in.mOp->deepCopy() : nullptr; return *this; }
|
||||
DynamicO& operator=(DynamicO&& in)
|
||||
{ mOp = in.mOp ? in.mOp->deepCopy() : nullptr; return *this; }
|
||||
|
||||
bool init() const { return mOp != nullptr; }
|
||||
|
||||
template <class Op>
|
||||
DynamicO(const Op& op) : mOp(std::make_shared<DynamicOperation<T,Op>>(op)) {}
|
||||
|
||||
DynamicO(const std::shared_ptr<DynamicOperationBase<T>>& op) :
|
||||
mOp(op) {}
|
||||
|
||||
template <class X>
|
||||
inline T get(const DExtTX<X>& pos) const { return mOp->get(pos.reduce()); }
|
||||
template <class X>
|
||||
inline DynamicO& set(const DExtTX<X>& pos) { mOp->set(pos.reduce()); return *this; }
|
||||
inline DExtT rootSteps(std::intptr_t iPtrNum = 0) const { return mOp->rootSteps(iPtrNum); }
|
||||
inline DynamicExpression loop(const DynamicExpression& exp) const { return mOp->loop(exp); }
|
||||
inline const T* data() const { return mOp->data(); }
|
||||
};
|
||||
/*
|
||||
template <class Op1>
|
||||
class TwoOp : public OperationTemplate<typename Op2::value_type,TwoOp<Op1>>
|
||||
{
|
||||
private:
|
||||
|
||||
Op1 mOp1;
|
||||
typename Op1::value_type mOp2; // mOp1.data()->mOp
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Op2::value_type value_type;
|
||||
typedef value_type T;
|
||||
|
||||
TwoOp(const Op1& op1);
|
||||
|
||||
template <class ET>
|
||||
inline T get(const ET& pos) const;
|
||||
};
|
||||
*/
|
||||
template <class Operation, class... Indices>
|
||||
auto mkDynOutOp(const Operation& op, const std::shared_ptr<Indices>&... inds)
|
||||
{
|
||||
return DynamicO<OpH<OperationRoot<typename Operation::value_type,
|
||||
typename Indices::RangeType...>>>
|
||||
(DynamicOuterOp<typename Operation::value_type,Operation,
|
||||
typename Indices::RangeType...>(op, inds...));
|
||||
}
|
||||
/*
|
||||
template <class Operation, class... Indices>
|
||||
auto mkDynOutOp(const std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<typename Operatrion::value_type,Ranges...>>>>& dyn,
|
||||
const Operation& op, const std::shared_ptr<Indices>&... inds)
|
||||
{
|
||||
return DynamicO<OpH<OperationRoot<typename Operation::value_type,
|
||||
typename Indices::RangeType...>>>
|
||||
(DynamicOuterOp<typename Operation::value_type,Operation,
|
||||
typename Indices::RangeType...>(dyn, op, inds...));
|
||||
}
|
||||
*/
|
||||
// Build plan
|
||||
/*
|
||||
template <class Operation>
|
||||
class OperationBuilder
|
||||
{
|
||||
|
||||
};
|
||||
*/
|
||||
} // namespace MultiArrayTools
|
||||
|
||||
#endif
|
30
src/include/extensions/math.h
Normal file
30
src/include/extensions/math.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
#ifdef regFunc1
|
||||
|
||||
regFunc1(exp)
|
||||
regFunc1(exp2)
|
||||
regFunc1(expm1)
|
||||
regFunc1(log)
|
||||
regFunc1(log10)
|
||||
regFunc1(log2)
|
||||
regFunc1(log1p)
|
||||
regFunc1(sqrt)
|
||||
regFunc1(cbrt)
|
||||
regFunc1(sin)
|
||||
regFunc1(cos)
|
||||
regFunc1(tan)
|
||||
regFunc1(asin)
|
||||
regFunc1(acos)
|
||||
regFunc1(atan)
|
||||
regFunc1(sinh)
|
||||
regFunc1(cosh)
|
||||
regFunc1(tanh)
|
||||
regFunc1(asinh)
|
||||
regFunc1(acosh)
|
||||
regFunc1(atanh)
|
||||
regFunc1(erf)
|
||||
regFunc1(erfc)
|
||||
regFunc1(tgamma)
|
||||
regFunc1(lgamma)
|
||||
|
||||
#endif
|
109
src/include/functional_multi_array.cc.h
Normal file
109
src/include/functional_multi_array.cc.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
|
||||
#include "functional_multi_array.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
|
||||
/****************************
|
||||
* FunctionalMultiArray *
|
||||
****************************/
|
||||
|
||||
template <bool FISSTATIC>
|
||||
struct Application
|
||||
{
|
||||
template <typename T, class Function, typename Meta>
|
||||
static inline T apply(const std::shared_ptr<Function>& f, const Meta& m)
|
||||
{
|
||||
return (*f)(m);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Application<true>
|
||||
{
|
||||
template <typename T, class Function, typename Meta>
|
||||
static inline T apply(const std::shared_ptr<Function>& f, const Meta& m)
|
||||
{
|
||||
return Function::apply(m);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges,
|
||||
const std::shared_ptr<Function>& func) :
|
||||
MultiArrayBase<T,SRanges...>(ranges...), mFunc(func) {}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges) :
|
||||
MultiArrayBase<T,SRanges...>(ranges...) {}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const typename CRange::Space& space) :
|
||||
MultiArrayBase<T,SRanges...>(space) {}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const typename CRange::Space& space,
|
||||
const std::shared_ptr<Function>& func) :
|
||||
MultiArrayBase<T,SRanges...>(space), mFunc(func) {}
|
||||
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
const T& FunctionalMultiArray<T,Function,SRanges...>::operator[](const IndexType& i) const
|
||||
{
|
||||
mVal = Application<Function::FISSTATIC>::template apply<T,Function,typename IndexType::MetaType>(mFunc, i.meta());
|
||||
return mVal;
|
||||
}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
const T& FunctionalMultiArray<T,Function,SRanges...>::at(const typename CRange::IndexType::MetaType& meta) const
|
||||
{
|
||||
mVal = Application<Function::FISSTATIC>::template apply<T,Function,typename IndexType::MetaType>(mFunc,meta);
|
||||
return mVal;
|
||||
}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
const T* FunctionalMultiArray<T,Function,SRanges...>::data() const
|
||||
{
|
||||
return &mVal;
|
||||
}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
bool FunctionalMultiArray<T,Function,SRanges...>::isConst() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
bool FunctionalMultiArray<T,Function,SRanges...>::isSlice() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > FunctionalMultiArray<T,Function,SRanges...>::anonymous(bool slice) const
|
||||
{
|
||||
assert(0); // think about it carefully
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
ConstOperationRoot<T,SRanges...> FunctionalMultiArray<T,Function,SRanges...>::
|
||||
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
||||
{
|
||||
if(not mMaPtr){
|
||||
mMaPtr = std::make_shared<MAType>( MAB::mRange->space() );
|
||||
(*mMaPtr)(inds...) = exec(inds...);
|
||||
}
|
||||
return ConstOperationRoot<T,SRanges...>( *mMaPtr, inds... );
|
||||
}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
auto FunctionalMultiArray<T,Function,SRanges...>::
|
||||
exec(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
||||
-> Operation<T,Function,MetaOperationRoot<SRanges>...>
|
||||
{
|
||||
return mkOperation( mFunc, MetaOperationRoot<SRanges>( inds ) ... );
|
||||
}
|
||||
|
||||
} // namespace MultiArrayTools
|
127
src/include/functional_multi_array.h
Normal file
127
src/include/functional_multi_array.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
|
||||
#ifndef __functional_multi_array__
|
||||
#define __functional_multi_array__
|
||||
|
||||
#include "multi_array_base.h"
|
||||
#include "slice.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <bool HASMETACONT>
|
||||
struct ToMAObject
|
||||
{
|
||||
template <class Index>
|
||||
static auto mk(const std::shared_ptr<Index>& i)
|
||||
-> MultiArray<typename Index::MetaType, typename Index::RangeType>
|
||||
{
|
||||
assert(0); // deprecated
|
||||
vector<typename Index::MetaType> vv(i->range()->size());
|
||||
for(Index j = (*i); j.pos() != j.max(); ++j){
|
||||
vv[j.pos()] = j.meta();
|
||||
}
|
||||
return MultiArray<typename Index::MetaType, typename Index::RangeType>( i->range(), vv );
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ToMAObject<true>
|
||||
{
|
||||
template <class Index>
|
||||
static auto mk(const std::shared_ptr<Index>& i)
|
||||
-> ConstSlice<typename Index::MetaType, typename Index::RangeType>
|
||||
{
|
||||
return ConstSlice<typename Index::MetaType, typename Index::RangeType>( i->range(), i->metaPtr() );
|
||||
}
|
||||
};
|
||||
|
||||
template <class Index>
|
||||
auto mkMAObject(const std::shared_ptr<Index>& i)
|
||||
-> std::shared_ptr<decltype(ToMAObject<Index::RangeType::HASMETACONT>::mk(i))>
|
||||
{
|
||||
return std::make_shared<decltype(ToMAObject<Index::RangeType::HASMETACONT>::mk(i))>
|
||||
(ToMAObject<Index::RangeType::HASMETACONT>::mk(i));
|
||||
}
|
||||
|
||||
template <bool HASMETACONT>
|
||||
struct ToOpObject
|
||||
{
|
||||
template <class Index>
|
||||
static auto mk(const std::shared_ptr<Index>& ind)
|
||||
-> ConstOperationRoot<typename Index::MetaType,
|
||||
typename Index::RangeType>
|
||||
{
|
||||
return ConstOperationRoot<typename Index::MetaType,
|
||||
typename Index::RangeType>( mkMAObject(ind), ind);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ToOpObject<false>
|
||||
{
|
||||
template <class Index>
|
||||
static auto mk(const std::shared_ptr<Index>& ind)
|
||||
-> MetaOperationRoot<typename Index::RangeType>
|
||||
{
|
||||
return MetaOperationRoot<typename Index::RangeType>( ind );
|
||||
}
|
||||
};
|
||||
|
||||
template <class Index>
|
||||
auto mkOpObject(const std::shared_ptr<Index>& i)
|
||||
-> decltype(ToOpObject<Index::RangeType::HASMETACONT>::mk(i))
|
||||
{
|
||||
return ToOpObject<Index::RangeType::HASMETACONT>::mk(i);
|
||||
}
|
||||
|
||||
template <typename T, class Function, class... SRanges>
|
||||
class FunctionalMultiArray : public MultiArrayBase<T,SRanges...>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ContainerRange<T,SRanges...> CRange;
|
||||
typedef MultiArrayBase<T,SRanges...> MAB;
|
||||
typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType;
|
||||
typedef MultiArray<T,SRanges...> MAType;
|
||||
typedef T value_type;
|
||||
|
||||
private:
|
||||
mutable T mVal;
|
||||
std::shared_ptr<Function> mFunc;
|
||||
|
||||
mutable std::shared_ptr<MAType> mMaPtr;
|
||||
|
||||
public:
|
||||
|
||||
DEFAULT_MEMBERS(FunctionalMultiArray);
|
||||
FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges, const std::shared_ptr<Function>& func);
|
||||
FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges);
|
||||
FunctionalMultiArray(const typename CRange::Space& space);
|
||||
FunctionalMultiArray(const typename CRange::Space& space, const std::shared_ptr<Function>& func);
|
||||
|
||||
virtual const T& operator[](const IndexType& i) const override;
|
||||
virtual const T& at(const typename CRange::IndexType::MetaType& meta) const override;
|
||||
virtual const T* data() const override;
|
||||
|
||||
virtual bool isConst() const override;
|
||||
virtual bool isSlice() const override;
|
||||
|
||||
virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymous(bool slice = false) const override;
|
||||
|
||||
auto exec(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
||||
-> Operation<T,Function,MetaOperationRoot<SRanges>...>;
|
||||
|
||||
virtual ConstOperationRoot<T,SRanges...>
|
||||
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace MultiArrayTools
|
||||
|
||||
/* ========================= *
|
||||
* --- TEMPLATE CODE --- *
|
||||
* ========================= */
|
||||
|
||||
|
||||
#endif
|
398
src/include/helper_tools.cc.h
Normal file
398
src/include/helper_tools.cc.h
Normal file
|
@ -0,0 +1,398 @@
|
|||
|
||||
#include "helper_tools.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
template <typename... T>
|
||||
std::ostream& operator<<(std::ostream& out, const std::tuple<T...>& tp)
|
||||
{
|
||||
PackNum<sizeof...(T)-1>::printTuple(out, tp);
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class RangeType>
|
||||
auto getIndex(std::shared_ptr<RangeType> range)
|
||||
-> std::shared_ptr<typename RangeType::IndexType>
|
||||
{
|
||||
return std::make_shared<typename RangeType::IndexType>(range);
|
||||
}
|
||||
|
||||
template <class RangeType>
|
||||
auto getIndex()
|
||||
-> std::shared_ptr<typename RangeType::IndexType>
|
||||
{
|
||||
static_assert( RangeType::defaultable,
|
||||
/*typeid(typename RangeType).name() + */" is not defaultable" );
|
||||
static auto f = RangeType::factory();
|
||||
static auto r = std::dynamic_pointer_cast<RangeType>( f.create() );
|
||||
return std::make_shared<typename RangeType::IndexType>(r);
|
||||
}
|
||||
|
||||
template <class... RangeTypes>
|
||||
auto mkMulti(std::shared_ptr<RangeTypes>... ranges)
|
||||
-> std::shared_ptr<MultiRange<RangeTypes...> >
|
||||
{
|
||||
MultiRangeFactory<RangeTypes...> mrf( ranges... );
|
||||
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template <size_t N>
|
||||
struct IndexToRangeTuple
|
||||
{
|
||||
template <class... IndexTypes>
|
||||
static inline void set(std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>& out,
|
||||
const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||
{
|
||||
std::get<N>(out) = std::get<N>(indices)->range();
|
||||
IndexToRangeTuple<N-1>::set(out,indices);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct IndexToRangeTuple<0>
|
||||
{
|
||||
template <class... IndexTypes>
|
||||
static inline void set(std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>& out,
|
||||
const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||
{
|
||||
std::get<0>(out) = std::get<0>(indices)->range();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <class... IndexTypes>
|
||||
auto indexToRangeTuple(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||
-> std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>
|
||||
{
|
||||
std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...> out;
|
||||
IndexToRangeTuple<sizeof...(IndexTypes)-1>::set(out, indices);
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class... IndexTypes>
|
||||
auto mkMIndex(std::shared_ptr<IndexTypes>... indices)
|
||||
-> decltype( getIndex( mkMulti( indices->range()... ) ) )
|
||||
{
|
||||
auto mi = getIndex( mkMulti( indices->range()... ) );
|
||||
(*mi)( indices... );
|
||||
return mi;
|
||||
}
|
||||
|
||||
template <class... IndexTypes>
|
||||
auto mkMIndex(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||
-> decltype( getIndex( mkMulti( indexToRangeTuple(indices) ) ) )
|
||||
{
|
||||
auto mi = getIndex( mkMulti( indexToRangeTuple(indices) ) );
|
||||
(*mi)( indices );
|
||||
return mi;
|
||||
}
|
||||
|
||||
|
||||
template <class Index>
|
||||
auto mkIndexW(const std::shared_ptr<Index>& ind)
|
||||
-> std::shared_ptr<IndexW>
|
||||
{
|
||||
return std::make_shared<IndexWrapper<Index>>(ind);
|
||||
}
|
||||
|
||||
template <SpaceType STYPE, class Op, class MA, class... RangeTypes>
|
||||
auto mkGenMapR(const std::tuple<Op,MA>& f, std::shared_ptr<RangeTypes>... ranges)
|
||||
-> std::shared_ptr<GenMapRange<MapORType<Op,STYPE>,Op,STYPE,RangeTypes...> >
|
||||
{
|
||||
GenMapRangeFactory<MapORType<Op,STYPE>,Op,STYPE,RangeTypes...> mrf(f, ranges... );
|
||||
return createExplicit( mrf );
|
||||
}
|
||||
|
||||
template <SpaceType STYPE, class ORType, class Op, class MA, class... RangeTypes>
|
||||
auto mkGenMapRwith(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& f,
|
||||
std::shared_ptr<RangeTypes>... ranges)
|
||||
-> std::shared_ptr<GenMapRange<ORType,Op,STYPE,RangeTypes...> >
|
||||
{
|
||||
GenMapRangeFactory<ORType,Op,STYPE,RangeTypes...> mrf(outr, f, ranges... );
|
||||
return createExplicit( mrf );
|
||||
}
|
||||
|
||||
template <SpaceType STYPE, class Op, class MA, class... IndexTypes>
|
||||
auto mkGenMapI(const std::tuple<Op,MA>& f, std::shared_ptr<IndexTypes>... indices)
|
||||
-> decltype( getIndex( mkGenMapR<STYPE>( f, indices->range()... ) ) )
|
||||
{
|
||||
auto mi = getIndex( mkGenMapR<STYPE>( f, indices->range()... ) );
|
||||
(*mi)(indices...);
|
||||
return mi;
|
||||
}
|
||||
|
||||
template <class Op, class MA, class... RangeTypes>
|
||||
auto mkMapR(const std::tuple<Op,MA>& f, std::shared_ptr<RangeTypes>... ranges)
|
||||
-> decltype( mkGenMapR<SpaceType::ANY>(f, ranges... ) )
|
||||
{
|
||||
return mkGenMapR<SpaceType::ANY>(f, ranges... );
|
||||
}
|
||||
|
||||
template <class ORType, class Op, class MA, class... RangeTypes>
|
||||
auto mkMapRwith(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& f,
|
||||
std::shared_ptr<RangeTypes>... ranges)
|
||||
-> decltype( mkGenMapRwith<SpaceType::ANY>(outr, f, ranges... ) )
|
||||
{
|
||||
return mkGenMapRwith<SpaceType::ANY>(outr, f, ranges... );
|
||||
}
|
||||
|
||||
template <class Func, class... Indices>
|
||||
auto mkMapR(const std::shared_ptr<Func>& func, const std::shared_ptr<Indices>&... is)
|
||||
-> decltype( mkMapR( mkMapOp( func, is... ), is->range()... ) )
|
||||
{
|
||||
return mkMapR( mkMapOp( func, is... ), is->range()... );
|
||||
}
|
||||
|
||||
template <class ORType, class Func, class... Indices>
|
||||
auto mkMapRwith(const std::shared_ptr<ORType>& outr, const std::shared_ptr<Func>& func, const std::shared_ptr<Indices>&... is)
|
||||
-> decltype( mkMapRwith(outr, mkMapOp( func, is... ), is->range()... ) )
|
||||
{
|
||||
return mkMapRwith(outr, mkMapOp( func, is... ), is->range()... );
|
||||
}
|
||||
|
||||
template <class Op, class MA, class... IndexTypes>
|
||||
auto mkMapI(const std::tuple<Op,MA>& f, std::shared_ptr<IndexTypes>... indices)
|
||||
-> decltype( mkGenMapI<SpaceType::ANY>(f, indices... ) )
|
||||
{
|
||||
return mkGenMapI<SpaceType::ANY>(f, indices... );
|
||||
}
|
||||
|
||||
template <class... RangeTypes>
|
||||
auto mkMulti(std::tuple<std::shared_ptr<RangeTypes>...> rangesTuple)
|
||||
-> std::shared_ptr<MultiRange<RangeTypes...>>
|
||||
{
|
||||
MultiRangeFactory<RangeTypes...> mrf( rangesTuple );
|
||||
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
|
||||
}
|
||||
|
||||
template <class RangeFactory>
|
||||
auto createExplicit(RangeFactory& rf)
|
||||
-> std::shared_ptr<typename RangeFactory::oType>
|
||||
{
|
||||
return std::dynamic_pointer_cast<typename RangeFactory::oType>( rf.create() );
|
||||
}
|
||||
|
||||
template <class RangeFactory>
|
||||
auto createExplicit(std::shared_ptr<RangeFactory> rfp)
|
||||
-> std::shared_ptr<typename RangeFactory::oType>
|
||||
{
|
||||
return std::dynamic_pointer_cast<typename RangeFactory::oType>( rfp->create() );
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto createRange(const vector<char>& cvec)
|
||||
-> std::shared_ptr<Range>
|
||||
{
|
||||
const char* dp = cvec.data();
|
||||
auto ff = createRangeFactory(&dp);
|
||||
auto rbptr = ff->create();
|
||||
assert(rbptr->spaceType() == Range::STYPE);
|
||||
// CATCH CAST ERROR HERE !!!
|
||||
return std::dynamic_pointer_cast<Range>( rbptr );
|
||||
}
|
||||
|
||||
inline auto createRange(const vector<char>* cvec, int metaType, size_t size)
|
||||
-> std::shared_ptr<RangeBase>
|
||||
{
|
||||
auto f = createSingleRangeFactory(cvec, metaType, size);
|
||||
return f->create();
|
||||
}
|
||||
|
||||
inline auto createRangeA(const vector<char>* cvec, int metaType, size_t size)
|
||||
-> std::shared_ptr<AnonymousRange>
|
||||
{
|
||||
AnonymousRangeFactory arf(createRange(cvec, metaType, size));
|
||||
return createExplicit(arf);
|
||||
}
|
||||
|
||||
inline auto cvecMetaCast(const std::shared_ptr<SingleRange<vector<char>,SpaceType::ANY>>& r, int metaType)
|
||||
-> std::shared_ptr<RangeBase>
|
||||
{
|
||||
return createRange(&r->get(0), metaType, r->size());
|
||||
}
|
||||
|
||||
inline auto cvecMetaCastA(const std::shared_ptr<SingleRange<vector<char>,SpaceType::ANY>>& r, int metaType)
|
||||
-> std::shared_ptr<AnonymousRange>
|
||||
{
|
||||
return createRangeA(&r->get(0), metaType, r->size());
|
||||
}
|
||||
|
||||
template <class Range, typename... Args>
|
||||
auto createRangeE(Args&&... args)
|
||||
-> std::shared_ptr<Range>
|
||||
{
|
||||
typename Range::FType f(args...);
|
||||
return createExplicit(f);
|
||||
}
|
||||
|
||||
template <size_t N, class MArray>
|
||||
auto rptr(const MArray& ma)
|
||||
-> decltype(ma.template getRangePtr<N>())
|
||||
{
|
||||
return ma.template getRangePtr<N>();
|
||||
}
|
||||
|
||||
|
||||
template <class MArray>
|
||||
auto dynamic(const MArray& ma, bool slice)
|
||||
-> std::shared_ptr<MultiArrayBase<typename MArray::value_type,DynamicRange>>
|
||||
{
|
||||
DynamicRangeFactory drf(ma.range()->space());
|
||||
if(slice){
|
||||
return std::make_shared<ConstSlice<typename MArray::value_type,DynamicRange>>
|
||||
( std::dynamic_pointer_cast<DynamicRange>( drf.create() ),
|
||||
ma.data() );
|
||||
}
|
||||
else {
|
||||
return std::make_shared<MultiArray<typename MArray::value_type,DynamicRange>>
|
||||
( std::dynamic_pointer_cast<DynamicRange>( drf.create() ),
|
||||
ma.vdata() );
|
||||
}
|
||||
}
|
||||
|
||||
template <class MArray>
|
||||
auto mdynamic(MArray& ma, bool slice)
|
||||
-> std::shared_ptr<MutableMultiArrayBase<typename MArray::value_type,DynamicRange>>
|
||||
{
|
||||
DynamicRangeFactory drf(ma.range()->space());
|
||||
if(slice){
|
||||
return std::make_shared<Slice<typename MArray::value_type,DynamicRange>>
|
||||
( std::dynamic_pointer_cast<DynamicRange>( drf.create() ),
|
||||
ma.data() );
|
||||
}
|
||||
else {
|
||||
return std::make_shared<MultiArray<typename MArray::value_type,DynamicRange>>
|
||||
( std::dynamic_pointer_cast<DynamicRange>( drf.create() ),
|
||||
ma.vdata() );
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template <size_t N>
|
||||
struct CopyRanges
|
||||
{
|
||||
template <class Space1, class Space2>
|
||||
static inline void exec(const Space1& space1, Space2& space2)
|
||||
{
|
||||
std::get<N>(space2) = std::get<N>(space1);
|
||||
CopyRanges<N-1>::exec(space1,space2);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct CopyRanges<0>
|
||||
{
|
||||
template <class Space1, class Space2>
|
||||
static inline void exec(const Space1& space1, Space2& space2)
|
||||
{
|
||||
std::get<0>(space2) = std::get<0>(space1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T, class Range1, class... RangeTypes>
|
||||
auto anonToDynView(const MultiArrayBase<T,Range1,RangeTypes...,AnonymousRange>& ma)
|
||||
-> ConstSlice<T,Range1,RangeTypes...,DynamicRange>
|
||||
{
|
||||
constexpr size_t LAST = sizeof...(RangeTypes)+1;
|
||||
DynamicRangeFactory drf(rptr<LAST>(ma)->orig());
|
||||
std::tuple<std::shared_ptr<Range1>,std::shared_ptr<RangeTypes>...,
|
||||
std::shared_ptr<DynamicRange>> mNSpace;
|
||||
CopyRanges<LAST-1>::exec(ma.range()->space(),mNSpace);
|
||||
std::get<LAST>(mNSpace) = createExplicit( drf );
|
||||
return ConstSlice<T,Range1,RangeTypes...,DynamicRange>(mNSpace, ma.data());
|
||||
}
|
||||
|
||||
template <typename T, class Range1, class... RangeTypes>
|
||||
auto anonToDynView(MutableMultiArrayBase<T,Range1,RangeTypes...,AnonymousRange>& ma)
|
||||
-> Slice<T,Range1,RangeTypes...,DynamicRange>
|
||||
{
|
||||
constexpr size_t LAST = sizeof...(RangeTypes)+1;
|
||||
DynamicRangeFactory drf(rptr<LAST>(ma)->orig());
|
||||
std::tuple<std::shared_ptr<Range1>,std::shared_ptr<RangeTypes>...,
|
||||
std::shared_ptr<DynamicRange>> mNSpace;
|
||||
CopyRanges<LAST-1>::exec(ma.range()->space(),mNSpace);
|
||||
std::get<LAST>(mNSpace) = createExplicit( drf );
|
||||
return Slice<T,Range1,RangeTypes...,DynamicRange>(mNSpace, ma.data());
|
||||
}
|
||||
|
||||
template <typename T, class Range1, class... RangeTypes>
|
||||
auto dynToAnonMove(MultiArray<T,Range1,RangeTypes...,DynamicRange>&& ma)
|
||||
-> MultiArray<T,Range1,RangeTypes...,AnonymousRange>
|
||||
{
|
||||
constexpr size_t LAST = sizeof...(RangeTypes)+1;
|
||||
AnonymousRangeFactory arf(rptr<LAST>(ma)->orig());
|
||||
std::tuple<std::shared_ptr<Range1>,std::shared_ptr<RangeTypes>...,
|
||||
std::shared_ptr<AnonymousRange>> mNSpace;
|
||||
CopyRanges<LAST-1>::exec(ma.range()->space(),mNSpace);
|
||||
std::get<LAST>(mNSpace) = createExplicit( arf );
|
||||
return ma.format(mNSpace);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto anonToDynView(const MultiArrayBase<T,AnonymousRange>& ma)
|
||||
-> ConstSlice<T,DynamicRange>
|
||||
{
|
||||
DynamicRangeFactory drf(rptr<0>(ma)->orig());
|
||||
auto mNSpace = std::make_tuple( createExplicit( drf ) );
|
||||
return ConstSlice<T,DynamicRange>(mNSpace, ma.data());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto anonToDynView(MutableMultiArrayBase<T,AnonymousRange>& ma)
|
||||
-> Slice<T,DynamicRange>
|
||||
{
|
||||
DynamicRangeFactory drf(rptr<0>(ma)->orig());
|
||||
auto mNSpace = std::make_tuple( createExplicit( drf ) );
|
||||
return Slice<T,DynamicRange>(mNSpace, ma.data());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto dynToAnonMove(MultiArray<T,DynamicRange>&& ma)
|
||||
-> MultiArray<T,AnonymousRange>
|
||||
{
|
||||
AnonymousRangeFactory arf(rptr<0>(ma)->orig());
|
||||
auto mNSpace = std::make_tuple( createExplicit( arf ) );
|
||||
return ma.format(mNSpace);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto metaSlice(const std::shared_ptr<Range>& r)
|
||||
-> ConstSlice<typename Range::MetaType,ClassicRange>
|
||||
{
|
||||
ClassicRF crf(r->size());
|
||||
return ConstSlice<typename Range::MetaType,ClassicRange>( createExplicit(crf), &r->get(0) );
|
||||
}
|
||||
|
||||
template <class Range, class ORange>
|
||||
auto metaSlice(const std::shared_ptr<Range>& r, const std::shared_ptr<ORange>& ro)
|
||||
-> ConstSlice<typename Range::MetaType,ORange>
|
||||
{
|
||||
return ConstSlice<typename Range::MetaType,ORange>( ro, &r->get(0) );
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
auto mkArray(const std::shared_ptr<Ranges>&... rs)
|
||||
-> MultiArray<T,Ranges...>
|
||||
{
|
||||
return MultiArray<T,Ranges...>(rs...);
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
auto mkArray(const std::shared_ptr<Ranges>&... rs, const T& val)
|
||||
-> MultiArray<T,Ranges...>
|
||||
{
|
||||
return MultiArray<T,Ranges...>(rs..., val);
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
auto mkArrayPtr(const std::shared_ptr<Ranges>&... rs)
|
||||
-> std::shared_ptr<MultiArray<T,Ranges...>>
|
||||
{
|
||||
return std::make_shared<MultiArray<T,Ranges...>>(rs...);
|
||||
}
|
||||
|
||||
}
|
239
src/include/helper_tools.h
Normal file
239
src/include/helper_tools.h
Normal file
|
@ -0,0 +1,239 @@
|
|||
|
||||
#ifndef __helper_tools_h__
|
||||
#define __helper_tools_h__
|
||||
|
||||
#include "base_def.h"
|
||||
#include "slice.h"
|
||||
#include <ostream>
|
||||
#include "pack_num.h"
|
||||
#include "map_range.h"
|
||||
#include <functional>
|
||||
#include "xfor/iloop.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <typename... T>
|
||||
std::ostream& operator<<(std::ostream& out, const std::tuple<T...>& tp);
|
||||
|
||||
template <class RangeType>
|
||||
auto getIndex(std::shared_ptr<RangeType> range)
|
||||
-> std::shared_ptr<typename RangeType::IndexType>;
|
||||
|
||||
// only if 'RangeType' is defaultable and unique (Singleton)
|
||||
template <class RangeType>
|
||||
auto getIndex() -> std::shared_ptr<typename RangeType::IndexType>;
|
||||
|
||||
template <class... RangeTypes>
|
||||
auto mkMulti(std::shared_ptr<RangeTypes>... ranges)
|
||||
-> std::shared_ptr<MultiRange<RangeTypes...> >;
|
||||
|
||||
template <class Op, SpaceType XSTYPE>
|
||||
using MapORType = SingleRange<typename Op::value_type,XSTYPE>;
|
||||
|
||||
template <SpaceType STYPE, class Op, class MA, class... RangeTypes>
|
||||
auto mkGenMapR(const std::tuple<Op,MA>& f, std::shared_ptr<RangeTypes>... ranges)
|
||||
-> std::shared_ptr<GenMapRange<MapORType<Op,STYPE>,Op,STYPE,RangeTypes...> >;
|
||||
|
||||
template <SpaceType STYPE, class ORType, class Op, class MA, class... RangeTypes>
|
||||
auto mkGenMapRwith(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& f,
|
||||
std::shared_ptr<RangeTypes>... ranges)
|
||||
-> std::shared_ptr<GenMapRange<ORType,Op,STYPE,RangeTypes...> >;
|
||||
|
||||
template <SpaceType STYPE, class Op, class MA, class... IndexTypes>
|
||||
auto mkGenMapI(const std::tuple<Op,MA>& f, std::shared_ptr<IndexTypes>... indices)
|
||||
-> decltype( getIndex( mkGenMapR<STYPE>( f, indices->range()... ) ) );
|
||||
|
||||
template <class Op, class MA, class... RangeTypes>
|
||||
auto mkMapR(const std::tuple<Op,MA>& f, std::shared_ptr<RangeTypes>... ranges)
|
||||
-> decltype( mkGenMapR<SpaceType::ANY>(f, ranges... ) );
|
||||
|
||||
template <class ORType, class Op, class MA, class... RangeTypes>
|
||||
auto mkMapRwith(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& f, std::shared_ptr<RangeTypes>... ranges)
|
||||
-> decltype( mkGenMapRwith<SpaceType::ANY>(outr, f, ranges... ) );
|
||||
|
||||
template <class Func, class... Indices>
|
||||
auto mkMapR(const std::shared_ptr<Func>& func, const std::shared_ptr<Indices>&... is)
|
||||
-> decltype( mkMapR( mkMapOp( func, is... ), is->range()... ) );
|
||||
|
||||
template <class ORType, class Func, class... Indices>
|
||||
auto mkMapRwith(const std::shared_ptr<ORType>& outr, const std::shared_ptr<Func>& func, const std::shared_ptr<Indices>&... is)
|
||||
-> decltype( mkMapRwith(outr, mkMapOp( func, is... ), is->range()... ) );
|
||||
|
||||
template <class Op, class MA, class... IndexTypes>
|
||||
auto mkMapI(const std::tuple<Op,MA>& f, std::shared_ptr<IndexTypes>... indices)
|
||||
-> decltype( mkGenMapI<SpaceType::ANY>(f, indices... ) );
|
||||
|
||||
template <class... IndexTypes>
|
||||
auto indexToRangeTuple(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||
-> std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>;
|
||||
|
||||
template <class... RangeTypes>
|
||||
auto mkMulti(std::tuple<std::shared_ptr<RangeTypes>...> rangesTuple)
|
||||
-> std::shared_ptr<MultiRange<RangeTypes...>>;
|
||||
|
||||
template <class... IndexTypes>
|
||||
auto mkMIndex(std::shared_ptr<IndexTypes>... indices)
|
||||
-> decltype( getIndex( mkMulti( indices.range()... ) ) );
|
||||
|
||||
template <class... IndexTypes>
|
||||
auto mkMIndex(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||
-> decltype( getIndex( mkMulti( indexToRangeTuple(indices) ) ) );
|
||||
|
||||
template <class Index>
|
||||
auto mkIndexW(const std::shared_ptr<Index>& ind)
|
||||
-> std::shared_ptr<IndexW>;
|
||||
|
||||
|
||||
template <class RangeFactory>
|
||||
auto createExplicit(RangeFactory& rf)
|
||||
-> std::shared_ptr<typename RangeFactory::oType>;
|
||||
|
||||
template <class RangeFactory>
|
||||
auto createExplicit(std::shared_ptr<RangeFactory> rfp)
|
||||
-> std::shared_ptr<typename RangeFactory::oType>;
|
||||
|
||||
template <class Range>
|
||||
auto createRange(const vector<char>& cvec)
|
||||
-> std::shared_ptr<Range>;
|
||||
|
||||
inline auto createRange(const vector<char>* cvec, int metaType, size_t size)
|
||||
-> std::shared_ptr<RangeBase>;
|
||||
|
||||
inline auto createRangeA(const vector<char>* cvec, int metaType, size_t size)
|
||||
-> std::shared_ptr<AnonymousRange>;
|
||||
|
||||
template <class Range, typename... Args>
|
||||
auto createRangeE(Args&&... args)
|
||||
-> std::shared_ptr<Range>;
|
||||
|
||||
template <size_t N, class MArray>
|
||||
auto rptr(const MArray& ma)
|
||||
-> decltype(ma.template getRangePtr<N>());
|
||||
|
||||
template <size_t I, class MIndex>
|
||||
auto get(const std::shared_ptr<MIndex>& i)
|
||||
-> decltype(i->template getPtr<I>())
|
||||
{
|
||||
return i->template getPtr<I>();
|
||||
}
|
||||
|
||||
template <class MArray>
|
||||
auto dynamic(const MArray& ma, bool slice = false)
|
||||
-> std::shared_ptr<MultiArrayBase<typename MArray::value_type,DynamicRange>>;
|
||||
|
||||
template <class MArray>
|
||||
auto mdynamic(MArray& ma, bool slice)
|
||||
-> std::shared_ptr<MutableMultiArrayBase<typename MArray::value_type,DynamicRange>>;
|
||||
|
||||
template <typename T, class Range1, class... RangeTypes>
|
||||
auto anonToDynView(const MultiArrayBase<T,Range1,RangeTypes...,AnonymousRange>& ma)
|
||||
-> ConstSlice<T,Range1,RangeTypes...,DynamicRange>;
|
||||
|
||||
template <typename T, class Range1, class... RangeTypes>
|
||||
auto anonToDynView(MutableMultiArrayBase<T,Range1,RangeTypes...,AnonymousRange>& ma)
|
||||
-> Slice<T,Range1,RangeTypes...,DynamicRange>;
|
||||
|
||||
template <typename T, class Range1, class... RangeTypes>
|
||||
auto dynToAnonMove(MultiArray<T,Range1,RangeTypes...,DynamicRange>&& ma)
|
||||
-> MultiArray<T,Range1,RangeTypes...,AnonymousRange>;
|
||||
|
||||
template <typename T>
|
||||
auto anonToDynView(const MultiArrayBase<T,AnonymousRange>& ma)
|
||||
-> ConstSlice<T,DynamicRange>;
|
||||
|
||||
template <typename T>
|
||||
auto anonToDynView(MutableMultiArrayBase<T,AnonymousRange>& ma)
|
||||
-> Slice<T,DynamicRange>;
|
||||
|
||||
template <typename T>
|
||||
auto dynToAnonMove(MultiArray<T,DynamicRange>&& ma)
|
||||
-> MultiArray<T,AnonymousRange>;
|
||||
|
||||
template <class Range>
|
||||
auto metaSlice(const std::shared_ptr<Range>& r)
|
||||
-> ConstSlice<typename Range::MetaType,ClassicRange>;
|
||||
|
||||
template <class Range, class ORange>
|
||||
auto metaSlice(const std::shared_ptr<Range>& r, const std::shared_ptr<ORange>& ro)
|
||||
-> ConstSlice<typename Range::MetaType,ORange>;
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
auto mkArray(const std::shared_ptr<Ranges>&... rs)
|
||||
-> MultiArray<T,Ranges...>;
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
auto mkArrayPtr(const std::shared_ptr<Ranges>&... rs)
|
||||
-> std::shared_ptr<MultiArray<T,Ranges...>>;
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
auto mkArray(const std::shared_ptr<Ranges>&... rs, const T& val)
|
||||
-> MultiArray<T,Ranges...>;
|
||||
|
||||
template <class OpTp, class IndTp, class VarTp, class LTp>
|
||||
auto mkILoop(const OpTp& opTp, const IndTp& indTp, const VarTp& varTp, const LTp& lTp,
|
||||
const std::array<size_t,std::tuple_size<LTp>::value>& umpos,
|
||||
const std::array<size_t,std::tuple_size<VarTp>::value>& setzero)
|
||||
-> MultiArrayHelper::ILoop<OpTp,IndTp,VarTp,LTp>
|
||||
{
|
||||
return MultiArrayHelper::ILoop<OpTp,IndTp,VarTp,LTp>(opTp, indTp, varTp, lTp, umpos, setzero);
|
||||
}
|
||||
|
||||
template <class CF>
|
||||
auto mkPILoop(const CF& cf)
|
||||
-> MultiArrayHelper::PILoop<CF>
|
||||
{
|
||||
return MultiArrayHelper::PILoop<CF>(cf);
|
||||
}
|
||||
|
||||
template <class IndexType>
|
||||
inline void For(const std::shared_ptr<IndexType>& ind, const std::function<void(void)>& ll)
|
||||
{
|
||||
for((*ind) = 0; ind->pos() != ind->max(); ++(*ind)){
|
||||
ll();
|
||||
}
|
||||
}
|
||||
|
||||
// parallel:
|
||||
template <class IndexType>
|
||||
inline void PFor(const std::shared_ptr<IndexType>& ind,
|
||||
const std::function<void(const std::shared_ptr<IndexType>&)>& ll)
|
||||
{
|
||||
const int max = static_cast<int>(ind->max());
|
||||
int i = 0;
|
||||
#pragma omp parallel shared(ind,ll) private(i)
|
||||
{
|
||||
#pragma omp for nowait
|
||||
for(i = 0; i < max; i++) {
|
||||
auto ii = getIndex( ind->range() );
|
||||
((*ii) = i)();
|
||||
ll(ii);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Index>
|
||||
inline auto mkOp(const std::shared_ptr<Index>& i)
|
||||
-> decltype(std::declval<FunctionalMultiArray<typename Index::MetaType,
|
||||
identity<typename Index::MetaType>,typename Index::RangeType> >
|
||||
().exec(i))
|
||||
{
|
||||
FunctionalMultiArray<typename Index::MetaType,
|
||||
identity<typename Index::MetaType>,
|
||||
typename Index::RangeType> fma(i->range());
|
||||
return fma.exec(i);
|
||||
}
|
||||
|
||||
template <typename R, typename... Ts>
|
||||
struct Func
|
||||
{
|
||||
static inline std::shared_ptr<function<R,Ts...>> mk(const std::function<R(Ts...)>& ll)
|
||||
{
|
||||
return std::make_shared<function<R,Ts...>>(ll);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
476
src/include/high_level_operation.cc.h
Normal file
476
src/include/high_level_operation.cc.h
Normal file
|
@ -0,0 +1,476 @@
|
|||
|
||||
#include "high_level_operation.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <typename T, class Op>
|
||||
DynamicO<T> mkDynOp1(const Op& op)
|
||||
{
|
||||
return DynamicO<T>(op);
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
template <class... Indices>
|
||||
template <class Op, class... Ops>
|
||||
void HighLevelOpBase<ROP>::RetT<Indices...>::appendOuterM(const Op& op, const Ops&... ops)
|
||||
{
|
||||
// does not check anything regarding input !!!
|
||||
if(outer.init()){
|
||||
outer = mkDynOp1<size_t>(mkMOp<size_t>(outer,op,ops...));
|
||||
}
|
||||
else {
|
||||
outer = mkDynOp1<size_t>(mkMOp<size_t>(op,ops...));
|
||||
}
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
template <class... Indices>
|
||||
void HighLevelOpBase<ROP>::RetT<Indices...>::appendOuterM()
|
||||
{}
|
||||
|
||||
template <class ROP>
|
||||
template <class... Indices>
|
||||
void HighLevelOpBase<ROP>::RetT<Indices...>::appendOuter(const DynamicO<size_t>& in)
|
||||
{
|
||||
if(in.init()){
|
||||
if(outer.init()){
|
||||
outer = mkDynOp1<size_t>(mkMOp<size_t>(outer,in));
|
||||
}
|
||||
else {
|
||||
outer = in;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
template <class... Indices>
|
||||
void HighLevelOpBase<ROP>::RetT<Indices...>::appendOuter(const RetT& in)
|
||||
{
|
||||
appendOuter(in.outer);
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpRoot<ROP>::HighLevelOpRoot(const ROP& op) : mOp(op) {}
|
||||
|
||||
template <class ROP>
|
||||
bool HighLevelOpRoot<ROP>::root() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
template <class... Inds>
|
||||
auto HighLevelOpRoot<ROP>::xcreate(const std::shared_ptr<Inds>&... inds)
|
||||
-> typename B::template RetT<Inds...>
|
||||
{
|
||||
assert(0);
|
||||
return typename B::template RetT<Inds...>();
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
ROP* HighLevelOpRoot<ROP>::get()
|
||||
{
|
||||
return &mOp;
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
auto HighLevelOpRoot<ROP>::vget()
|
||||
-> VOP*
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpValue<ROP>::HighLevelOpValue(const VOP& op) : mOp(op) {}
|
||||
|
||||
template <class ROP>
|
||||
bool HighLevelOpValue<ROP>::root() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
template <class... Inds>
|
||||
auto HighLevelOpValue<ROP>::xcreate(const std::shared_ptr<Inds>&... inds)
|
||||
-> typename B::template RetT<Inds...>
|
||||
{
|
||||
assert(0);
|
||||
return typename B::template RetT<Inds...>();
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
ROP* HighLevelOpValue<ROP>::get()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
auto HighLevelOpValue<ROP>::vget()
|
||||
-> VOP*
|
||||
{
|
||||
return &mOp;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template <size_t N>
|
||||
struct Create
|
||||
{
|
||||
template <class... Indices>
|
||||
struct cx
|
||||
{
|
||||
template <class ROP, class OpF, class... OPs>
|
||||
struct ccx
|
||||
{
|
||||
template <size_t M, class... DOPs>
|
||||
static inline void
|
||||
cccx(typename HighLevelOpBase<ROP>::template RetT<Indices...>& res,
|
||||
const std::array<std::shared_ptr<HighLevelOpBase<ROP>>,M>& in,
|
||||
const std::shared_ptr<Indices>&... inds,
|
||||
const OPs&... ops,
|
||||
const DOPs&... dops)
|
||||
{
|
||||
static_assert(N > 0, "N > 0 failed");
|
||||
auto& inn = std::get<N>(in);
|
||||
if(not inn->root()){
|
||||
auto dop = inn->create(inds...);
|
||||
auto op = *dop.op.data()->mOp;
|
||||
typedef decltype(op) OP;
|
||||
res.appendOuter(dop);
|
||||
assert(dop.op.init());
|
||||
Create<N-1>::template cx<Indices...>::template ccx<ROP,OpF,OP,OPs...>::template cccx<M>
|
||||
(res, in, inds..., op, ops..., dop, dops...);
|
||||
}
|
||||
else {
|
||||
auto op = inn->get();
|
||||
auto vop = inn->vget();
|
||||
typedef typename std::remove_reference<decltype(*op)>::type OP;
|
||||
typedef typename std::remove_reference<decltype(*vop)>::type VOP;
|
||||
if(op != nullptr){
|
||||
Create<N-1>::template cx<Indices...>::template ccx<ROP,OpF,OP,OPs...>::template cccx<M>
|
||||
(res, in, inds..., *op, ops..., dops...);
|
||||
}
|
||||
else {
|
||||
Create<N-1>::template cx<Indices...>::template ccx<ROP,OpF,VOP,OPs...>::template cccx<M>
|
||||
(res, in, inds..., *vop, ops..., dops...);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Create<0>
|
||||
{
|
||||
template <class... Indices>
|
||||
struct cx
|
||||
{
|
||||
template <class ROP, class OpF, class... OPs>
|
||||
struct ccx
|
||||
{
|
||||
template <size_t M, class... DOPs>
|
||||
static inline void
|
||||
cccx(typename HighLevelOpBase<ROP>::template RetT<Indices...>& res,
|
||||
const std::array<std::shared_ptr<HighLevelOpBase<ROP>>,M>& in,
|
||||
const std::shared_ptr<Indices>&... inds,
|
||||
const OPs&... ops,
|
||||
const DOPs&... dops)
|
||||
{
|
||||
auto& inn = std::get<0>(in);
|
||||
if(not inn->root()){
|
||||
auto dop = inn->create(inds...);
|
||||
auto op = *dop.op.data()->mOp;
|
||||
res.appendOuter(dop);
|
||||
res.op = mkDynOutOp(mkFOp<OpF>(op,ops...), inds...);
|
||||
assert(dop.op.init());
|
||||
res.appendOuterM(dop.op,dops.op...);
|
||||
}
|
||||
else {
|
||||
auto op = inn->get();
|
||||
auto vop = inn->vget();
|
||||
if(op != nullptr){
|
||||
res.op = mkDynOutOp(mkFOp<OpF>(*op,ops...), inds...);
|
||||
}
|
||||
else {
|
||||
res.op = mkDynOutOp(mkFOp<OpF>(*vop,ops...), inds...);
|
||||
}
|
||||
res.appendOuterM(dops.op...);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template <class ROP, class OpF, size_t N>
|
||||
HighLevelOp<ROP,OpF,N>::HighLevelOp(std::array<std::shared_ptr<HighLevelOpBase<ROP>>,N> in) : mIn(in) {}
|
||||
|
||||
template <class ROP, class OpF, size_t N>
|
||||
bool HighLevelOp<ROP,OpF,N>::root() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class ROP, class OpF, size_t N>
|
||||
ROP* HighLevelOp<ROP,OpF,N>::get()
|
||||
{
|
||||
assert(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class ROP, class OpF, size_t N>
|
||||
auto HighLevelOp<ROP,OpF,N>::vget()
|
||||
-> VOP*
|
||||
{
|
||||
assert(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class ROP, class OpF, size_t N>
|
||||
template <class... Inds>
|
||||
auto HighLevelOp<ROP,OpF,N>::xcreate(const std::shared_ptr<Inds>&... inds)
|
||||
-> typename B::template RetT<Inds...>
|
||||
{
|
||||
typename B::template RetT<Inds...> res;
|
||||
Create<N-1>::template cx<Inds...>::template ccx<ROP,OpF>::template cccx<N>
|
||||
(res,mIn,inds...);
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpHolder<ROP>::HighLevelOpHolder(const std::shared_ptr<HighLevelOpBase<ROP>>& op) : mOp(op) {}
|
||||
|
||||
template <class ROP>
|
||||
bool HighLevelOpHolder<ROP>::root() const
|
||||
{
|
||||
return mOp->root();
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
template <class... Inds>
|
||||
auto HighLevelOpHolder<ROP>::create(const std::shared_ptr<Inds>&... inds) const
|
||||
-> decltype(mOp->create(inds...))
|
||||
{
|
||||
return mOp->create(inds...);
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
auto HighLevelOpHolder<ROP>::get()
|
||||
-> decltype(mOp->get())
|
||||
{
|
||||
return mOp->get();
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
std::shared_ptr<HighLevelOpBase<ROP>> HighLevelOpHolder<ROP>::op() const
|
||||
{
|
||||
return mOp;
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpHolder<ROP> HighLevelOpHolder<ROP>::operator*(const HighLevelOpHolder& in) const
|
||||
{
|
||||
return HighLevelOpHolder<ROP>
|
||||
( std::make_shared<HighLevelOp<ROP,multipliesx<double,double>,2>>
|
||||
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,2>({mOp, in.mOp}) ) );
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpHolder<ROP> HighLevelOpHolder<ROP>::operator+(const HighLevelOpHolder& in) const
|
||||
{
|
||||
return HighLevelOpHolder<ROP>
|
||||
( std::make_shared<HighLevelOp<ROP,plusx<double,double>,2>>
|
||||
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,2>({mOp, in.mOp}) ) );
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpHolder<ROP> HighLevelOpHolder<ROP>::operator-(const HighLevelOpHolder& in) const
|
||||
{
|
||||
return HighLevelOpHolder<ROP>
|
||||
( std::make_shared<HighLevelOp<ROP,minusx<double,double>,2>>
|
||||
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,2>({mOp, in.mOp}) ) );
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpHolder<ROP> HighLevelOpHolder<ROP>::operator/(const HighLevelOpHolder& in) const
|
||||
{
|
||||
return HighLevelOpHolder<ROP>
|
||||
( std::make_shared<HighLevelOp<ROP,dividesx<double,double>,2>>
|
||||
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,2>({mOp, in.mOp}) ) );
|
||||
}
|
||||
|
||||
template <class F, class ROP, class... ROPs>
|
||||
HighLevelOpHolder<ROP> mkSFunc(const HighLevelOpHolder<ROP>& a, const HighLevelOpHolder<ROPs>&... as)
|
||||
{
|
||||
constexpr size_t N = sizeof...(ROPs)+1;
|
||||
return HighLevelOpHolder<ROP>
|
||||
( std::make_shared<HighLevelOp<ROP,F,N>>
|
||||
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,N>({a.op(), as.op()...}) ) );
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
template <class... Indices>
|
||||
HighLevelOpHolder<ROP>& HighLevelOpHolder<ROP>::xassign(const HighLevelOpHolder& in,
|
||||
const std::shared_ptr<DynamicIndex>& di,
|
||||
const std::shared_ptr<Indices>&... is)
|
||||
{
|
||||
const size_t dim = di->dim();
|
||||
if(dim > 2){
|
||||
auto ci1 = di->getP(dim-2)->reduced();
|
||||
auto ci2 = di->getP(dim-1)->reduced();
|
||||
assert(ci1 != nullptr);
|
||||
assert(ci2 != nullptr);
|
||||
auto odi = mkSubSpaceX(di, dim-2);
|
||||
auto mi = mkMIndex(is..., odi);
|
||||
this->assign(in, mi, ci1, ci2);
|
||||
}
|
||||
else {
|
||||
assert(dim == 2 or dim == 1);
|
||||
auto ci1 = di->getP(dim-1)->reduced();
|
||||
assert(ci1 != nullptr);
|
||||
auto odi = mkSubSpaceX(di, dim-1);
|
||||
auto mi = mkMIndex(is..., odi);
|
||||
this->assign(in, mi, ci1);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
template <class... Indices>
|
||||
HighLevelOpHolder<ROP>& HighLevelOpHolder<ROP>::xplus(const HighLevelOpHolder& in,
|
||||
const std::shared_ptr<DynamicIndex>& di,
|
||||
const std::shared_ptr<Indices>&... is)
|
||||
{
|
||||
const size_t dim = di->dim();
|
||||
if(dim > 2){
|
||||
auto ci1 = di->getP(dim-2)->reduced();
|
||||
auto ci2 = di->getP(dim-1)->reduced();
|
||||
assert(ci1 != nullptr);
|
||||
assert(ci2 != nullptr);
|
||||
auto odi = mkSubSpaceX(di, dim-2);
|
||||
auto mi = mkMIndex(is..., odi);
|
||||
this->plus(in, mi, ci1, ci2);
|
||||
}
|
||||
else {
|
||||
assert(dim == 2 or dim == 1);
|
||||
auto ci1 = di->getP(dim-1)->reduced();
|
||||
assert(ci1 != nullptr);
|
||||
auto odi = mkSubSpaceX(di, dim-1);
|
||||
auto mi = mkMIndex(is..., odi);
|
||||
this->plus(in, mi, ci1);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Ind1, class Ind2, class... Inds>
|
||||
std::string printInd(const std::shared_ptr<Ind1>& ind1, const std::shared_ptr<Ind2>& ind2,
|
||||
const std::shared_ptr<Inds>&... inds)
|
||||
{
|
||||
return std::to_string(reinterpret_cast<std::intptr_t>(ind1.get())) + "(" +
|
||||
std::to_string(ind1->max()) + "), " + printInd(ind2, inds...);
|
||||
}
|
||||
|
||||
template <class Ind1>
|
||||
std::string printInd(const std::shared_ptr<Ind1>& ind1)
|
||||
{
|
||||
return std::to_string(reinterpret_cast<std::intptr_t>(ind1.get())) + "(" + std::to_string(ind1->max()) + ")";
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
template <class MIndex, class... Indices>
|
||||
HighLevelOpHolder<ROP>& HighLevelOpHolder<ROP>::assign(const HighLevelOpHolder& in,
|
||||
const std::shared_ptr<MIndex>& mi,
|
||||
const std::shared_ptr<Indices>&... inds)
|
||||
{
|
||||
auto xx = mkArrayPtr<double>(nullr());
|
||||
ROP& opr = *mOp->get();
|
||||
if(in.root()){
|
||||
auto inx = in;
|
||||
opr.par().assign( *inx.get(), mkMIndex(mi,inds...) )();
|
||||
return *this;
|
||||
}
|
||||
auto loop = mkPILoop
|
||||
( [&opr,&in,&xx,&inds...,this](){
|
||||
auto inx = in;
|
||||
auto dop = inx.create(inds...);
|
||||
DynamicO<size_t> gexp;
|
||||
if(dop.outer.init()){
|
||||
gexp = mkDynOp1<size_t>(mkMOp<size_t>(dop.outer,dop.op));
|
||||
}
|
||||
else {
|
||||
gexp = mkDynOp1<size_t>(mkMOp<size_t>(dop.op));
|
||||
}
|
||||
auto xloop = mkILoop(std::make_tuple(*dop.op.data()->mOp),
|
||||
std::make_tuple(inds...),
|
||||
std::make_tuple(xx),
|
||||
std::make_tuple(opr.assign( *dop.op.data()->mOp,
|
||||
mkMIndex(inds...) )),
|
||||
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
|
||||
return mkGetExpr(gexp, xloop); });
|
||||
mi->pifor(1,loop)();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
template <class MIndex, class... Indices>
|
||||
HighLevelOpHolder<ROP>& HighLevelOpHolder<ROP>::plus(const HighLevelOpHolder& in,
|
||||
const std::shared_ptr<MIndex>& mi,
|
||||
const std::shared_ptr<Indices>&... inds)
|
||||
{
|
||||
auto xx = mkArrayPtr<double>(nullr());
|
||||
ROP& opr = *mOp->get();
|
||||
if(in.root()){
|
||||
auto inx = in;
|
||||
opr.par().plus( *inx.get(), mkMIndex(mi,inds...) )();
|
||||
return *this;
|
||||
}
|
||||
auto loop = mkPILoop
|
||||
( [&opr,&in,&xx,&inds...,this](){
|
||||
auto inx = in;
|
||||
auto dop = inx.create(inds...);
|
||||
DynamicO<size_t> gexp;
|
||||
if(dop.outer.init()){
|
||||
gexp = mkDynOp1<size_t>(mkMOp<size_t>(dop.outer,dop.op));
|
||||
}
|
||||
else {
|
||||
gexp = mkDynOp1<size_t>(mkMOp<size_t>(dop.op));
|
||||
}
|
||||
auto xloop = mkILoop(std::make_tuple(*dop.op.data()->mOp),
|
||||
std::make_tuple(inds...),
|
||||
std::make_tuple(xx),
|
||||
std::make_tuple(opr.plus( *dop.op.data()->mOp,
|
||||
mkMIndex(inds...) )),
|
||||
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
|
||||
return mkGetExpr(gexp, xloop); });
|
||||
mi->pifor(1,loop)();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpHolder<ROP> mkHLO(const ROP& op)
|
||||
{
|
||||
return HighLevelOpHolder<ROP>(std::make_shared<HighLevelOpRoot<ROP>>( op ) );
|
||||
}
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpHolder<ROP> mkHLOV(double val)
|
||||
{
|
||||
return HighLevelOpHolder<ROP>(std::make_shared<HighLevelOpValue<ROP>>
|
||||
( OperationValue<double>(val) ) );
|
||||
}
|
||||
|
||||
|
||||
#define SP " "
|
||||
#define regFunc1(fff) template <class ROP> \
|
||||
HighLevelOpHolder<ROP> hl_##fff (const HighLevelOpHolder<ROP>& in) \
|
||||
{ return HighLevelOpHolder<ROP>( std::make_shared<HighLevelOp<ROP,x_##fff <double>,1>> \
|
||||
( std::array<std::shared_ptr<HighLevelOpBase<ROP>>,1>( {in.op()} ) ) ); } \
|
||||
|
||||
#include "extensions/math.h"
|
||||
#undef regFunc1
|
||||
#undef SP
|
||||
|
||||
}
|
||||
|
267
src/include/high_level_operation.h
Normal file
267
src/include/high_level_operation.h
Normal file
|
@ -0,0 +1,267 @@
|
|||
|
||||
#ifndef __high_level_operation_h__
|
||||
#define __high_level_operation_h__
|
||||
|
||||
#include "base_def.h"
|
||||
#include "ranges/rheader.h"
|
||||
#include "dynamic_operation.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
typedef ClassicRange CR;
|
||||
typedef CR::IndexType CI;
|
||||
typedef std::shared_ptr<CI> CIP;
|
||||
|
||||
typedef OperationRoot<double,CR,DynamicRange> OpCD;
|
||||
typedef OperationRoot<double,DynamicRange> OpD;
|
||||
extern template class OperationRoot<double,CR,DynamicRange>;
|
||||
extern template class OperationRoot<double,DynamicRange>;
|
||||
|
||||
template <typename T, class Op>
|
||||
DynamicO<T> mkDynOp1(const Op& op);
|
||||
|
||||
std::shared_ptr<DynamicIndex> mkSubSpaceX(const std::shared_ptr<DynamicIndex>& di, size_t max);
|
||||
|
||||
template <class ROP>
|
||||
class HighLevelOpBase
|
||||
{
|
||||
public:
|
||||
|
||||
typedef OperationValue<double> VOP;
|
||||
|
||||
template <class... Indices>
|
||||
struct RetT
|
||||
{
|
||||
DynamicO<OpH<OperationRoot<double,typename Indices::RangeType...>>> op;
|
||||
DynamicO<size_t> outer;
|
||||
|
||||
template <class Op, class... Ops>
|
||||
void appendOuterM(const Op& op, const Ops&... ops);
|
||||
|
||||
void appendOuterM();
|
||||
void appendOuter(const DynamicO<size_t>& in);
|
||||
void appendOuter(const RetT& in);
|
||||
|
||||
};
|
||||
|
||||
virtual bool root() const = 0;
|
||||
|
||||
#define reg_ind1(I1) virtual RetT<I1> create \
|
||||
(const std::shared_ptr<I1>& ind1) = 0
|
||||
#define reg_ind2(I1,I2) virtual RetT<I1,I2> create \
|
||||
(const std::shared_ptr<I1>& ind1,const std::shared_ptr<I2>& ind2) = 0
|
||||
#define reg_ind3(I1,I2,I3) virtual RetT<I1,I2,I3> create \
|
||||
(const std::shared_ptr<I1>& ind1,const std::shared_ptr<I2>& ind2,const std::shared_ptr<I3>& ind3) = 0
|
||||
|
||||
#include "hl_reg_ind.h"
|
||||
|
||||
#undef reg_ind1
|
||||
#undef reg_ind2
|
||||
#undef reg_ind3
|
||||
|
||||
virtual ROP* get() = 0;
|
||||
virtual VOP* vget() = 0;
|
||||
|
||||
};
|
||||
|
||||
template <class ROP>
|
||||
class HighLevelOpRoot : public HighLevelOpBase<ROP>
|
||||
{
|
||||
private:
|
||||
typedef HighLevelOpBase<ROP> B;
|
||||
typedef typename B::VOP VOP;
|
||||
|
||||
template <class... Inds>
|
||||
typename B::template RetT<Inds...> xcreate(const std::shared_ptr<Inds>&... inds);
|
||||
|
||||
ROP mOp;
|
||||
public:
|
||||
|
||||
HighLevelOpRoot(const ROP& op);
|
||||
|
||||
virtual bool root() const override final;
|
||||
|
||||
#define reg_ind1(I1) virtual typename B::template RetT<I1> create \
|
||||
(const std::shared_ptr<I1>& ind1) \
|
||||
override final { return xcreate(ind1); }
|
||||
#define reg_ind2(I1,I2) virtual typename B::template RetT<I1,I2> create \
|
||||
(const std::shared_ptr<I1>& ind1, const std::shared_ptr<I2>& ind2) \
|
||||
override final { return xcreate(ind1,ind2); }
|
||||
#define reg_ind3(I1,I2,I3) virtual typename B::template RetT<I1,I2,I3> create \
|
||||
(const std::shared_ptr<I1>& ind1, const std::shared_ptr<I2>& ind2, const std::shared_ptr<I3>& ind3) \
|
||||
override final { return xcreate(ind1,ind2,ind3); }
|
||||
|
||||
#include "hl_reg_ind.h"
|
||||
|
||||
virtual ROP* get() override final;
|
||||
virtual VOP* vget() override final;
|
||||
|
||||
};
|
||||
|
||||
extern template class HighLevelOpBase<OpCD>;
|
||||
extern template class HighLevelOpBase<OpD>;
|
||||
extern template class HighLevelOpRoot<OpCD>;
|
||||
extern template class HighLevelOpRoot<OpD>;
|
||||
|
||||
template <class ROP>
|
||||
class HighLevelOpValue : public HighLevelOpBase<ROP>
|
||||
{
|
||||
private:
|
||||
typedef HighLevelOpBase<ROP> B;
|
||||
typedef typename B::VOP VOP;
|
||||
|
||||
template <class... Inds>
|
||||
typename B::template RetT<Inds...> xcreate(const std::shared_ptr<Inds>&... inds);
|
||||
|
||||
VOP mOp;
|
||||
public:
|
||||
|
||||
HighLevelOpValue(const VOP& vop);
|
||||
|
||||
virtual bool root() const override final;
|
||||
|
||||
#include "hl_reg_ind.h"
|
||||
|
||||
virtual ROP* get() override final;
|
||||
virtual VOP* vget() override final;
|
||||
|
||||
};
|
||||
|
||||
template <class OpF, class... Ops>
|
||||
auto mkFOp(const Ops&... ops)
|
||||
{
|
||||
return Operation<double,OpF,Ops...>(ops...);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class ROP, class OpF, size_t N>
|
||||
class HighLevelOp : public HighLevelOpBase<ROP>
|
||||
{
|
||||
public:
|
||||
typedef HighLevelOpBase<ROP> B;
|
||||
typedef typename B::VOP VOP;
|
||||
|
||||
private:
|
||||
std::array<std::shared_ptr<HighLevelOpBase<ROP>>,N> mIn;
|
||||
|
||||
template <class... Inds>
|
||||
auto xcreate(const std::shared_ptr<Inds>&... inds)
|
||||
-> typename B::template RetT<Inds...>;
|
||||
|
||||
public:
|
||||
HighLevelOp(std::array<std::shared_ptr<HighLevelOpBase<ROP>>,N> in);
|
||||
|
||||
virtual bool root() const override final;
|
||||
|
||||
virtual ROP* get() override final;
|
||||
virtual VOP* vget() override final;
|
||||
|
||||
#include "hl_reg_ind.h"
|
||||
|
||||
#undef reg_ind1
|
||||
#undef reg_ind2
|
||||
#undef reg_ind3
|
||||
};
|
||||
|
||||
extern template class HighLevelOp<OpCD,plusx<double,double>,2>;
|
||||
extern template class HighLevelOp<OpCD,minusx<double,double>,2>;
|
||||
extern template class HighLevelOp<OpCD,multipliesx<double,double>,2>;
|
||||
extern template class HighLevelOp<OpCD,dividesx<double,double>,2>;
|
||||
extern template class HighLevelOp<OpD,plusx<double,double>,2>;
|
||||
extern template class HighLevelOp<OpD,minusx<double,double>,2>;
|
||||
extern template class HighLevelOp<OpD,multipliesx<double,double>,2>;
|
||||
extern template class HighLevelOp<OpD,dividesx<double,double>,2>;
|
||||
|
||||
#define regFunc1(fff) \
|
||||
extern template class HighLevelOp<OpCD,x_##fff<double>,1>; \
|
||||
extern template class HighLevelOp<OpD,x_##fff<double>,1>;
|
||||
#include "extensions/math.h"
|
||||
#undef regFunc1
|
||||
|
||||
template <class ROP>
|
||||
class HighLevelOpHolder
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<HighLevelOpBase<ROP>> mOp;
|
||||
|
||||
public:
|
||||
HighLevelOpHolder() = default;
|
||||
HighLevelOpHolder(const HighLevelOpHolder& in) = default;
|
||||
HighLevelOpHolder(HighLevelOpHolder&& in) = default;
|
||||
HighLevelOpHolder& operator=(const HighLevelOpHolder& in) = default;
|
||||
HighLevelOpHolder& operator=(HighLevelOpHolder&& in) = default;
|
||||
|
||||
HighLevelOpHolder(const std::shared_ptr<HighLevelOpBase<ROP>>& op);
|
||||
|
||||
bool root() const;
|
||||
|
||||
template <class... Inds>
|
||||
auto create(const std::shared_ptr<Inds>&... inds) const
|
||||
-> decltype(mOp->create(inds...));
|
||||
|
||||
auto get() -> decltype(mOp->get());
|
||||
|
||||
std::shared_ptr<HighLevelOpBase<ROP>> op() const;
|
||||
HighLevelOpHolder operator*(const HighLevelOpHolder& in) const;
|
||||
HighLevelOpHolder operator+(const HighLevelOpHolder& in) const;
|
||||
HighLevelOpHolder operator-(const HighLevelOpHolder& in) const;
|
||||
HighLevelOpHolder operator/(const HighLevelOpHolder& in) const;
|
||||
|
||||
|
||||
template <class... Indices>
|
||||
HighLevelOpHolder& xassign(const HighLevelOpHolder& in,
|
||||
const std::shared_ptr<DynamicIndex>& di,
|
||||
const std::shared_ptr<Indices>&... is);
|
||||
|
||||
template <class... Indices>
|
||||
HighLevelOpHolder& xplus(const HighLevelOpHolder& in,
|
||||
const std::shared_ptr<DynamicIndex>& di,
|
||||
const std::shared_ptr<Indices>&... is);
|
||||
|
||||
template <class MIndex, class... Indices>
|
||||
HighLevelOpHolder& assign(const HighLevelOpHolder& in,
|
||||
const std::shared_ptr<MIndex>& mi,
|
||||
const std::shared_ptr<Indices>&... inds);
|
||||
|
||||
template <class MIndex, class... Indices>
|
||||
HighLevelOpHolder& plus(const HighLevelOpHolder& in,
|
||||
const std::shared_ptr<MIndex>& mi,
|
||||
const std::shared_ptr<Indices>&... inds);
|
||||
};
|
||||
|
||||
extern template class HighLevelOpHolder<OpCD>;
|
||||
extern template class HighLevelOpHolder<OpD>;
|
||||
|
||||
template <class F, class ROP, class... ROPs>
|
||||
HighLevelOpHolder<ROP> mkSFunc(const HighLevelOpHolder<ROP>& a, const HighLevelOpHolder<ROPs>&... as);
|
||||
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpHolder<ROP> mkHLO(const ROP& op);
|
||||
|
||||
template <class ROP>
|
||||
HighLevelOpHolder<ROP> mkHLOV(double val);
|
||||
|
||||
extern template HighLevelOpHolder<OpCD> mkHLO(const OpCD& op);
|
||||
extern template HighLevelOpHolder<OpD> mkHLO(const OpD& op);
|
||||
extern template HighLevelOpHolder<OpCD> mkHLOV(double val);
|
||||
extern template HighLevelOpHolder<OpD> mkHLOV(double val);
|
||||
|
||||
#define regFunc1(fff) template <class ROP> \
|
||||
HighLevelOpHolder<ROP> hl_##fff (const HighLevelOpHolder<ROP>& in);
|
||||
#include "extensions/math.h"
|
||||
#undef regFunc1
|
||||
|
||||
#define regFunc1(fff) template <class ROP> \
|
||||
HighLevelOpHolder<ROP> hl_##fff (const HighLevelOpHolder<ROP>& in); \
|
||||
extern template HighLevelOpHolder<OpCD> hl_##fff (const HighLevelOpHolder<OpCD>& in); \
|
||||
extern template HighLevelOpHolder<OpD> hl_##fff (const HighLevelOpHolder<OpD>& in);
|
||||
#include "extensions/math.h"
|
||||
#undef regFunc1
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
52
src/include/hl_reg_ind.h
Normal file
52
src/include/hl_reg_ind.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
|
||||
#ifndef __hl_reg_ind_h__
|
||||
#define __hl_reg_ind_h__
|
||||
|
||||
#include "ranges/rheader.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <class Index>
|
||||
struct RegIndNum
|
||||
{
|
||||
static constexpr size_t VALUE = -1;
|
||||
static constexpr size_t DEPTH = 0;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct RegIndNum<ClassicRange::IndexType>
|
||||
{
|
||||
static constexpr size_t VALUE = 0;
|
||||
static constexpr size_t DEPTH = 3;
|
||||
};
|
||||
|
||||
// to be returned by IndexWrapper
|
||||
struct RegIndInfo
|
||||
{
|
||||
size_t type;
|
||||
size_t depth;
|
||||
|
||||
template <class Index>
|
||||
RegIndInfo& set(const std::shared_ptr<Index>& i)
|
||||
{
|
||||
type = RegIndNum<Index>::VALUE;
|
||||
depth = RegIndNum<Index>::DEPTH;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef reg_ind1
|
||||
#ifdef reg_ind2
|
||||
#ifdef reg_ind3
|
||||
|
||||
reg_ind1(ClassicRange::IndexType);
|
||||
reg_ind2(ClassicRange::IndexType,ClassicRange::IndexType);
|
||||
reg_ind3(ClassicRange::IndexType,ClassicRange::IndexType,ClassicRange::IndexType);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
15
src/include/ma_assert.h
Normal file
15
src/include/ma_assert.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#define MA_ERRTAG __FILE__ << '@' << __LINE__ << '(' << __func__ << "): error"
|
||||
#define MA_WARNTAG __FILE__ << '@' << __LINE__ << ": warning"
|
||||
#define MA_ERROR(errmsg) {\
|
||||
std::stringstream ss;\
|
||||
ss << MA_ERRTAG << ": " << errmsg << std::flush;\
|
||||
throw std::runtime_error(ss.str()); }
|
||||
|
||||
#define MA_WARNING(errmsg) {\
|
||||
std::cerr << MA_WARNTAG << ": " << errmsg << std::endl; }
|
||||
|
||||
#define MA_ASSERT(statement, errmsg) if(not (statement)) { MA_ERROR(errmsg); }
|
696
src/include/map_range.cc.h
Normal file
696
src/include/map_range.cc.h
Normal file
|
@ -0,0 +1,696 @@
|
|||
|
||||
#include "map_range.h"
|
||||
#include <type_traits>
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace MultiArrayHelper;
|
||||
}
|
||||
|
||||
/**************
|
||||
* OpExpr *
|
||||
**************/
|
||||
|
||||
template <class Op, class Index, class Expr, SpaceType STYPE>
|
||||
OpExpr<Op,Index,Expr,STYPE>::OpExpr(const Op& mapf, const Index* ind,
|
||||
size_t step, Expr ex) :
|
||||
mIndPtr(ind), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()),
|
||||
mStep(step), mExpr( ex ),
|
||||
mOp(mapf),
|
||||
//mExt(ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
|
||||
mExt( mOp.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ).extend
|
||||
( ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ) ) )
|
||||
{
|
||||
assert(mIndPtr != nullptr);
|
||||
}
|
||||
|
||||
template <class Op, class Index, class Expr, SpaceType STYPE>
|
||||
inline void OpExpr<Op,Index,Expr,STYPE>::operator()(size_t mlast,
|
||||
ExtType last)
|
||||
{
|
||||
constexpr size_t NEXT = Op::SIZE;
|
||||
const ExtType nxpos = last;
|
||||
const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) );
|
||||
if(pos != mIndPtr->max()){
|
||||
const ExtType npos = last + mExt*pos;
|
||||
const size_t mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
|
||||
mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ) );
|
||||
}
|
||||
}
|
||||
|
||||
template <class Op, class Index, class Expr, SpaceType STYPE>
|
||||
inline void OpExpr<Op,Index,Expr,STYPE>::operator()(size_t mlast)
|
||||
{
|
||||
const ExtType last;
|
||||
constexpr size_t NEXT = Op::SIZE;
|
||||
const ExtType nxpos = last;
|
||||
const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) );
|
||||
if(pos != mIndPtr->max()){
|
||||
const ExtType npos = last + mExt*pos;
|
||||
const size_t mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
|
||||
mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Op, class Index, class Expr, SpaceType STYPE>
|
||||
auto OpExpr<Op,Index,Expr,STYPE>::rootSteps(std::intptr_t iPtrNum) const
|
||||
-> ExtType
|
||||
{
|
||||
return mOp.rootSteps(iPtrNum).extend( mExpr.rootSteps(iPtrNum) );
|
||||
//return mExpr.rootSteps(iPtrNum).extend( mOp.rootSteps(iPtrNum) );
|
||||
}
|
||||
|
||||
|
||||
// -> define in range_base.cc
|
||||
//std::shared_ptr<RangeFactoryBase> mkMULTI(const char** dp);
|
||||
|
||||
/******************
|
||||
* MapIndex *
|
||||
******************/
|
||||
|
||||
/*
|
||||
template <class MapF, class... Indices>
|
||||
MapIndex<MapF,Indices...>::MapIndex(const MapIndex<MapF,Indices...>& in) :
|
||||
IndexInterface<std::tuple<typename Indices::MetaType...> >(in)
|
||||
{
|
||||
RPackNum<sizeof...(Indices)-1>::copy(mIPack, in);
|
||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||
}
|
||||
|
||||
template <class MapF, class... Indices>
|
||||
MapIndex<MapF,Indices...>& MapIndex<MapF,Indices...>::operator=(const MapIndex<MapF,Indices...>& in)
|
||||
{
|
||||
IndexI::operator=(in);
|
||||
RPackNum<sizeof...(Indices)-1>::copy(mIPack, in);
|
||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||
return *this;
|
||||
}
|
||||
*/
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
template <class MRange>
|
||||
GenMapIndex<OIType,Op,XSTYPE,Indices...>::GenMapIndex(const std::shared_ptr<MRange>& range) :
|
||||
IndexInterface<GenMapIndex<OIType,Op,XSTYPE,Indices...>,typename Op::value_type>(range, 0)
|
||||
{
|
||||
RPackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
|
||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||
std::get<sizeof...(Indices)>(mBlockSizes) = 1;
|
||||
RPackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack); // has one more element!
|
||||
mOutIndex = std::make_shared<OIType>
|
||||
( std::dynamic_pointer_cast<RangeType>( IB::mRangePtr )->outRange()->begin() );
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
template <size_t DIR>
|
||||
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::up()
|
||||
{
|
||||
static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices");
|
||||
IB::mPos += RPackNum<sizeof...(Indices)-DIR-1>::blockSize( mIPack );
|
||||
RPackNum<DIR>::pp( mIPack );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
template <size_t DIR>
|
||||
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::down()
|
||||
{
|
||||
static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices");
|
||||
IB::mPos -= RPackNum<sizeof...(Indices)-DIR-1>::blockSize( mIPack );
|
||||
RPackNum<DIR>::mm( mIPack );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
template <size_t N>
|
||||
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::get() const -> decltype( *std::get<N>( mIPack ) )&
|
||||
{
|
||||
return *std::get<N>(mIPack);
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
template <size_t N>
|
||||
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::getPtr() const -> decltype( std::get<N>( mIPack ) )&
|
||||
{
|
||||
return std::get<N>(mIPack);
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::outIndex() const -> std::shared_ptr<OIType>
|
||||
{
|
||||
return mOutIndex;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::operator()(const std::shared_ptr<Indices>&... indices)
|
||||
{
|
||||
RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, indices...);
|
||||
RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, IB::mPos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
IndexType GenMapIndex<OIType,Op,XSTYPE,Indices...>::type() const
|
||||
{
|
||||
return IndexType::MULTI;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::operator=(size_t pos)
|
||||
{
|
||||
(*mOutIndex) = pos;
|
||||
IB::mPos = mOutIndex->pos();
|
||||
//RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, pos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::operator++()
|
||||
{
|
||||
//RPackNum<sizeof...(Indices)-1>::pp( mIPack );
|
||||
++(*mOutIndex);
|
||||
IB::mPos = mOutIndex->pos();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::operator--()
|
||||
{
|
||||
//RPackNum<sizeof...(Indices)-1>::mm( mIPack );
|
||||
--(*mOutIndex);
|
||||
IB::mPos = mOutIndex->pos();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
int GenMapIndex<OIType,Op,XSTYPE,Indices...>::pp(std::intptr_t idxPtrNum)
|
||||
{
|
||||
//int tmp = RPackNum<sizeof...(Indices)-1>::pp(mIPack, mBlockSizes, idxPtrNum);
|
||||
mOutIndex->pp(idxPtrNum);
|
||||
IB::mPos = mOutIndex->pos();
|
||||
//IB::mPos += tmp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
int GenMapIndex<OIType,Op,XSTYPE,Indices...>::mm(std::intptr_t idxPtrNum)
|
||||
{
|
||||
//int tmp = RPackNum<sizeof...(Indices)-1>::mm(mIPack, mBlockSizes, idxPtrNum);
|
||||
mOutIndex->mm(idxPtrNum);
|
||||
IB::mPos = mOutIndex->pos();
|
||||
//IB::mPos -= tmp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
std::string GenMapIndex<OIType,Op,XSTYPE,Indices...>::stringMeta() const
|
||||
{
|
||||
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr )->stringMeta(IB::mPos);
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
typename GenMapIndex<OIType,Op,XSTYPE,Indices...>::MetaType GenMapIndex<OIType,Op,XSTYPE,Indices...>::meta() const
|
||||
{
|
||||
//MetaType metaTuple;
|
||||
//RPackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, mIPack);
|
||||
//assert(0);
|
||||
return mOutIndex->meta();
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
GenMapIndex<OIType,Op,XSTYPE,Indices...>& GenMapIndex<OIType,Op,XSTYPE,Indices...>::at(const MetaType& metaPos)
|
||||
{
|
||||
//RPackNum<sizeof...(Indices)-1>::setMeta(mIPack, metaPos);
|
||||
//IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||
mOutIndex->at(metaPos);
|
||||
IB::mPos = mOutIndex->pos();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
size_t GenMapIndex<OIType,Op,XSTYPE,Indices...>::posAt(const MetaType& metaPos) const
|
||||
{
|
||||
return range()->outRange()->getMeta(metaPos);
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
size_t GenMapIndex<OIType,Op,XSTYPE,Indices...>::dim() const
|
||||
{
|
||||
return sizeof...(Indices);
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
bool GenMapIndex<OIType,Op,XSTYPE,Indices...>::first() const
|
||||
{
|
||||
return IB::mPos == 0;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
bool GenMapIndex<OIType,Op,XSTYPE,Indices...>::last() const
|
||||
{
|
||||
return IB::mPos == IB::mMax - 1;
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
std::shared_ptr<typename GenMapIndex<OIType,Op,XSTYPE,Indices...>::RangeType>
|
||||
GenMapIndex<OIType,Op,XSTYPE,Indices...>::range() const
|
||||
{
|
||||
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
template <size_t N>
|
||||
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::getPtr() -> decltype( std::get<N>( mIPack ) )&
|
||||
{
|
||||
return std::get<N>(mIPack);
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
size_t GenMapIndex<OIType,Op,XSTYPE,Indices...>::getStepSize(size_t n) const
|
||||
{
|
||||
if(n >= sizeof...(Indices)){
|
||||
assert(0);
|
||||
// throw !!
|
||||
}
|
||||
return mBlockSizes[n+1];
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
std::string GenMapIndex<OIType,Op,XSTYPE,Indices...>::id() const
|
||||
{
|
||||
return std::string("mul") + std::to_string(IB::mId);
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
void GenMapIndex<OIType,Op,XSTYPE,Indices...>::print(size_t offset) const
|
||||
{
|
||||
if(offset == 0){
|
||||
std::cout << " === " << std::endl;
|
||||
}
|
||||
for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; }
|
||||
std::cout << id() << "[" << reinterpret_cast<std::intptr_t>(this)
|
||||
<< "]" << "(" << IB::mRangePtr << "): " << meta() << std::endl;
|
||||
RPackNum<sizeof...(Indices)-1>::printIndex(mIPack, offset+1);
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
template <class Exprs>
|
||||
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::ifor(size_t step, Exprs exs) const
|
||||
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh
|
||||
(step, mIPack, mBlockSizes, OpExpr<Op,GenMapIndex<OIType,Op,XSTYPE,Indices...>,Exprs,XSTYPE>
|
||||
( range()->map(), this, step, exs ) ) )
|
||||
{
|
||||
return RPackNum<sizeof...(Indices)-1>::mkForh
|
||||
(0, mIPack, mBlockSizes, OpExpr<Op,GenMapIndex<OIType,Op,XSTYPE,Indices...>,Exprs,XSTYPE>
|
||||
( range()->map(), this, step, exs ) );
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
template <class Exprs>
|
||||
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::pifor(size_t step, Exprs exs) const
|
||||
-> decltype(ifor(step, exs))
|
||||
{
|
||||
return ifor(step, exs);
|
||||
}
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
template <class Exprs>
|
||||
auto GenMapIndex<OIType,Op,XSTYPE,Indices...>::iforh(size_t step, Exprs exs) const
|
||||
-> decltype(ifor(step, exs))
|
||||
{
|
||||
return ifor(step, exs);
|
||||
}
|
||||
|
||||
/*************************
|
||||
* MapRangeFactory *
|
||||
*************************/
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <class MA>
|
||||
GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::GenMapRangeFactory(const std::shared_ptr<ORType>& outr,
|
||||
const std::tuple<Op,MA>& mapf,
|
||||
const std::shared_ptr<Ranges>&... rs)
|
||||
{
|
||||
mProd = std::shared_ptr< GenMapRange<ORType,Op,XSTYPE,Ranges...> >
|
||||
( new GenMapRange<ORType,Op,XSTYPE,Ranges...>( outr, mapf, rs... ) );
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <class MA>
|
||||
GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::GenMapRangeFactory(const std::shared_ptr<ORType>& outr,
|
||||
const std::tuple<Op,MA>& mapf,
|
||||
const typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::Space& st)
|
||||
{
|
||||
mProd = std::shared_ptr< GenMapRange<ORType,Op,XSTYPE,Ranges...> >
|
||||
( new GenMapRange<ORType,Op,XSTYPE,Ranges...>( outr, mapf, st ) );
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <class MA>
|
||||
GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::GenMapRangeFactory(const std::tuple<Op,MA>& mapf,
|
||||
const std::shared_ptr<Ranges>&... rs)
|
||||
{
|
||||
mProd = std::shared_ptr< GenMapRange<ORType,Op,XSTYPE,Ranges...> >
|
||||
( new GenMapRange<ORType,Op,XSTYPE,Ranges...>( mapf, rs... ) );
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <class MA>
|
||||
GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::GenMapRangeFactory(const std::tuple<Op,MA>& mapf,
|
||||
const typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::Space& st)
|
||||
{
|
||||
mProd = std::shared_ptr< GenMapRange<ORType,Op,XSTYPE,Ranges...> >
|
||||
( new GenMapRange<ORType,Op,XSTYPE,Ranges...>( mapf, st ) );
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
std::shared_ptr<RangeBase> GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::create()
|
||||
{
|
||||
mProd = checkIfCreated( std::dynamic_pointer_cast<oType>( mProd )->mSpace );
|
||||
setSelf();
|
||||
return mProd;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
std::shared_ptr<RangeBase> GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>::checkIfCreated(const std::tuple<std::shared_ptr<Ranges>...>& ptp)
|
||||
{
|
||||
std::shared_ptr<RangeBase> out;
|
||||
bool check = false;
|
||||
for(auto& x: MapRangeFactoryProductMap::mAleadyCreated){
|
||||
if(x.second.size() == sizeof...(Ranges)){
|
||||
check = RPackNum<sizeof...(Ranges)-1>::checkIfCreated(ptp, x.second);
|
||||
if(check){
|
||||
out = x.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(not check){
|
||||
vector<std::intptr_t> pv(sizeof...(Ranges));
|
||||
RPackNum<sizeof...(Ranges)-1>::RangesToVec(ptp, pv);
|
||||
pv.push_back( reinterpret_cast<std::intptr_t>
|
||||
( &std::dynamic_pointer_cast<oType>( mProd )->mMapf ) );
|
||||
MapRangeFactoryProductMap::mAleadyCreated[mProd] = pv;
|
||||
out = mProd;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/******************
|
||||
* MapRange *
|
||||
******************/
|
||||
|
||||
template <SpaceType XSTYPE>
|
||||
struct OutRangeMaker
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct OutRangeMaker<SpaceType::ANY>
|
||||
{
|
||||
template <class MapF, class ORType>
|
||||
static void mk(std::shared_ptr<ORType>& outRange, MultiArray<size_t,ORType>& mapMult, const MapF& mapf)
|
||||
{
|
||||
std::map<typename MapF::value_type,size_t> mult;
|
||||
for(auto ii = mapf.begin(); ii.max() != ii.pos(); ++ii) {
|
||||
mult[mapf[ii]]++;
|
||||
}
|
||||
|
||||
vector<typename MapF::value_type> outmeta(mult.size());
|
||||
vector<size_t> outmult(mult.size());
|
||||
|
||||
size_t cnt = 0;
|
||||
for(auto& x: mult){
|
||||
outmeta[cnt] = x.first;
|
||||
outmult[cnt] = x.second;
|
||||
++cnt;
|
||||
}
|
||||
|
||||
typename ORType::FType orf(outmeta);
|
||||
outRange = std::dynamic_pointer_cast<ORType>( orf.create() );
|
||||
mapMult = MultiArray<size_t,ORType>( outRange, outmult );
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OutRangeMaker<SpaceType::NONE>
|
||||
{
|
||||
template <class MapF, class ORType>
|
||||
static void mk(std::shared_ptr<ORType>& outRange, MultiArray<size_t,ORType>& mapMult, const MapF& mapf)
|
||||
{
|
||||
static_assert( std::is_same<size_t,typename MapF::value_type>::value,
|
||||
"out range value type for NONE must be size_t" );
|
||||
size_t max = 0;
|
||||
for(auto ii = mapf.begin(); ii.max() != ii.pos(); ++ii) {
|
||||
max = mapf[ii]+1 > max ? mapf[ii]+1 : max;
|
||||
}
|
||||
vector<size_t> mult(max,0);
|
||||
for(auto ii = mapf.begin(); ii.max() != ii.pos(); ++ii) {
|
||||
mult[mapf[ii]]++;
|
||||
}
|
||||
|
||||
vector<size_t> outmult(mult.size());
|
||||
|
||||
size_t cnt = 0;
|
||||
for(auto& x: mult){
|
||||
outmult[cnt++] = x;
|
||||
}
|
||||
|
||||
typename ORType::FType orf(max);
|
||||
outRange = std::dynamic_pointer_cast<ORType>( orf.create() );
|
||||
mapMult = MultiArray<size_t,ORType>( outRange, outmult );
|
||||
}
|
||||
};
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <class MA>
|
||||
void GenMapRange<ORType,Op,XSTYPE,Ranges...>::mkOutRange(const MA& mapf)
|
||||
{
|
||||
//FunctionalMultiArray<typename MapF::value_type,MapF,Ranges...> fma(mSpace, mMapf);
|
||||
OutRangeMaker<XSTYPE>::mk(mOutRange,mMapMult,mapf);
|
||||
auto i = mapf.begin();
|
||||
mMapPos.resize(i.max());
|
||||
for(; i.pos() != i.max(); ++i){
|
||||
mMapPos[i.pos()] = mOutRange->getMeta( mapf[i] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <class MA>
|
||||
GenMapRange<ORType,Op,XSTYPE,Ranges...>::GenMapRange(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
|
||||
const std::shared_ptr<Ranges>&... rs) :
|
||||
mSpace(std::make_tuple(rs...)),
|
||||
mMapf(std::get<0>(mapf)),
|
||||
mOutRange(outr),
|
||||
mMapMult(mOutRange,0),
|
||||
mMapPos(std::get<1>(mapf).size(),mOutRange->size())
|
||||
{
|
||||
auto& ma = std::get<1>(mapf);
|
||||
auto jj = mMapMult.begin();
|
||||
for(auto ii = ma.begin(); ii.pos() != ii.max(); ++ii){
|
||||
++mMapMult[jj.at(ma[ii])];
|
||||
mMapPos[ii.pos()] = jj.pos();
|
||||
}
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <class MA>
|
||||
GenMapRange<ORType,Op,XSTYPE,Ranges...>::GenMapRange(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
|
||||
const Space& space) :
|
||||
mSpace(space),
|
||||
mMapf(std::get<0>(mapf)),
|
||||
mOutRange(outr),
|
||||
mMapMult(mOutRange,0),
|
||||
mMapPos(std::get<1>(mapf).size(),mOutRange->size())
|
||||
{
|
||||
auto& ma = std::get<1>(mapf);
|
||||
auto jj = mMapMult.begin();
|
||||
for(auto ii = ma.begin(); ii.pos() != ii.max(); ++ii){
|
||||
++mMapMult[jj.at(ma[ii])];
|
||||
mMapPos[ii.pos()] = jj.pos();
|
||||
}
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <class MA>
|
||||
GenMapRange<ORType,Op,XSTYPE,Ranges...>::GenMapRange(const std::tuple<Op,MA>& mapf,
|
||||
const std::shared_ptr<Ranges>&... rs) :
|
||||
mSpace(std::make_tuple(rs...)),
|
||||
mMapf(std::get<0>(mapf))
|
||||
{
|
||||
mkOutRange(std::get<1>(mapf));
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <class MA>
|
||||
GenMapRange<ORType,Op,XSTYPE,Ranges...>::GenMapRange(const std::tuple<Op,MA>& mapf, const Space& space) :
|
||||
mSpace( space ),
|
||||
mMapf(std::get<0>(mapf))
|
||||
{
|
||||
mkOutRange(std::get<1>(mapf));
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <size_t N>
|
||||
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::get() const -> decltype( *std::get<N>( mSpace ) )&
|
||||
{
|
||||
return *std::get<N>(mSpace);
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <size_t N>
|
||||
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::getPtr() const -> decltype( std::get<N>( mSpace ) )&
|
||||
{
|
||||
return std::get<N>(mSpace);
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::outRange() const -> std::shared_ptr<ORType>
|
||||
{
|
||||
return mOutRange;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
const Op& GenMapRange<ORType,Op,XSTYPE,Ranges...>::map() const
|
||||
{
|
||||
return mMapf;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
size_t GenMapRange<ORType,Op,XSTYPE,Ranges...>::dim() const
|
||||
{
|
||||
return sdim;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
size_t GenMapRange<ORType,Op,XSTYPE,Ranges...>::size() const
|
||||
{
|
||||
return mOutRange->size();
|
||||
//return RPackNum<sizeof...(Ranges)-1>::getSize(mSpace);
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
SpaceType GenMapRange<ORType,Op,XSTYPE,Ranges...>::spaceType() const
|
||||
{
|
||||
return SpaceType::ANY;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
const typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::Space& GenMapRange<ORType,Op,XSTYPE,Ranges...>::space() const
|
||||
{
|
||||
return mSpace;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
vector<size_t> GenMapRange<ORType,Op,XSTYPE,Ranges...>::typeNum() const
|
||||
{
|
||||
vector<size_t> o;
|
||||
RPackNum<sizeof...(Ranges)-1>::getTypeNum(o,mSpace);
|
||||
return o;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
size_t GenMapRange<ORType,Op,XSTYPE,Ranges...>::cmeta(char* target, size_t pos) const
|
||||
{
|
||||
//MetaType* xtarget = reinterpret_cast<MetaType*>(target);
|
||||
assert(0);
|
||||
return 0;
|
||||
//return RPackNum<sizeof...(Ranges)-1>::getCMeta(xtarget,pos,mSpace,cmetaSize());
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
size_t GenMapRange<ORType,Op,XSTYPE,Ranges...>::cmetaSize() const
|
||||
{
|
||||
return RPackNum<sizeof...(Ranges)-1>::getCMetaSize(mSpace);
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
std::string GenMapRange<ORType,Op,XSTYPE,Ranges...>::stringMeta(size_t pos) const
|
||||
{
|
||||
auto i = begin();
|
||||
i = pos;
|
||||
return "[ " + RPackNum<sizeof...(Ranges)-1>::getStringMeta(i) + " ]";
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
vector<char> GenMapRange<ORType,Op,XSTYPE,Ranges...>::data() const
|
||||
{
|
||||
DataHeader h = dataHeader();
|
||||
vector<char> out;
|
||||
//out.reserve(h.metaSize + sizeof(DataHeader));
|
||||
char* hcp = reinterpret_cast<char*>(&h);
|
||||
out.insert(out.end(), hcp, hcp + sizeof(DataHeader));
|
||||
RPackNum<sizeof...(Ranges)-1>::fillRangeDataVec(out, mSpace);
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
DataHeader GenMapRange<ORType,Op,XSTYPE,Ranges...>::dataHeader() const
|
||||
{
|
||||
DataHeader h;
|
||||
h.spaceType = static_cast<int>( SpaceType::ANY );
|
||||
h.metaSize = sizeof...(Ranges);
|
||||
h.multiple = 1;
|
||||
return h;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::IndexType GenMapRange<ORType,Op,XSTYPE,Ranges...>::begin() const
|
||||
{
|
||||
GenMapIndex<typename ORType::IndexType,Op,XSTYPE,typename Ranges::IndexType...>
|
||||
i( std::dynamic_pointer_cast<GenMapRange<ORType,Op,XSTYPE,Ranges...> >
|
||||
( std::shared_ptr<RangeBase>( RB::mThis ) ) );
|
||||
i = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::IndexType GenMapRange<ORType,Op,XSTYPE,Ranges...>::end() const
|
||||
{
|
||||
GenMapIndex<typename ORType::IndexType,Op,XSTYPE,typename Ranges::IndexType...>
|
||||
i( std::dynamic_pointer_cast<GenMapRange<ORType,Op,XSTYPE,Ranges...> >
|
||||
( std::shared_ptr<RangeBase>( RB::mThis )) );
|
||||
i = size();
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::mapMultiplicity() const
|
||||
-> const MultiArray<size_t,ORType>&
|
||||
{
|
||||
return mMapMult;
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::explMapMultiplicity() const
|
||||
-> ConstSlice<size_t,GenMapRange>
|
||||
{
|
||||
/*
|
||||
auto tmp = mMapMult;
|
||||
return tmp.format( std::dynamic_pointer_cast<GenMapRange<ORType,Op,XSTYPE,Ranges...> >
|
||||
( std::shared_ptr<RangeBase>( RB::mThis )) );
|
||||
*/
|
||||
return mMapMult.slformat(std::dynamic_pointer_cast<GenMapRange<ORType,Op,XSTYPE,Ranges...> >
|
||||
( std::shared_ptr<RangeBase>( RB::mThis )));
|
||||
}
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
vector<size_t> GenMapRange<ORType,Op,XSTYPE,Ranges...>::mapPos() const
|
||||
{
|
||||
return mMapPos;
|
||||
}
|
||||
|
||||
/*
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
template <class... ERanges>
|
||||
auto GenMapRange<ORType,Op,XSTYPE,Ranges...>::cat(const std::shared_ptr<MapRange<ERanges...> >& erange)
|
||||
-> std::shared_ptr<GenMapRange<Ranges...,ERanges...> >
|
||||
{
|
||||
auto crange = std::tuple_cat(mSpace, erange->space());
|
||||
MapRangeFactory<Ranges...,ERanges...> rf(crange);
|
||||
return std::dynamic_pointer_cast<MapRange<Ranges...,ERanges...> >(rf.create());
|
||||
}
|
||||
*/
|
||||
}
|
357
src/include/map_range.h
Normal file
357
src/include/map_range.h
Normal file
|
@ -0,0 +1,357 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
#ifndef __map_range_h__
|
||||
#define __map_range_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <tuple>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
#include "mbase_def.h"
|
||||
#include "ranges/range_base.h"
|
||||
#include "ranges/index_base.h"
|
||||
|
||||
#include "ranges/rpack_num.h"
|
||||
#include "map_range_factory_product_map.h"
|
||||
#include "ranges/x_to_string.h"
|
||||
#include "ranges/type_map.h"
|
||||
|
||||
#include "xfor/xfor.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
namespace
|
||||
{
|
||||
using namespace MultiArrayHelper;
|
||||
}
|
||||
|
||||
|
||||
template <class Func, class... Indices>
|
||||
auto mkMapOp(const std::shared_ptr<Func>& func,
|
||||
const std::shared_ptr<Indices>&... is)
|
||||
-> decltype(std::make_tuple(FunctionalMultiArray<typename Func::value_type,Func,
|
||||
typename Indices::RangeType...>().exec(is...),
|
||||
FunctionalMultiArray<typename Func::value_type,Func,
|
||||
typename Indices::RangeType...>()))
|
||||
{
|
||||
typedef FunctionalMultiArray<typename Func::value_type,Func,typename Indices::RangeType...> FMA;
|
||||
if(Func::FISSTATIC){
|
||||
FMA fma(is->range()...);
|
||||
return std::make_tuple(fma.exec(is...),fma);
|
||||
}
|
||||
else {
|
||||
FMA fma(is->range()...,func);
|
||||
return std::make_tuple(fma.exec(is...),fma);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class Op, class Index, class Expr, SpaceType STYPE = SpaceType::ANY>
|
||||
//template <class MapF, class IndexPack, class Expr, SpaceType STYPE = SpaceType::ANY>
|
||||
class OpExpr
|
||||
{
|
||||
public:
|
||||
//typedef typename Index::OIType OIType;
|
||||
//typedef SingleIndex<typename Op::value_type,STYPE> OIType;
|
||||
static constexpr size_t LAYER = Expr::LAYER + 1;
|
||||
static constexpr size_t SIZE = Expr::SIZE + Op::SIZE;
|
||||
|
||||
private:
|
||||
OpExpr() = default;
|
||||
|
||||
const Index* mIndPtr;
|
||||
//const OIType* mIndPtr;
|
||||
size_t mSPos;
|
||||
size_t mMax;
|
||||
size_t mStep;
|
||||
Expr mExpr;
|
||||
Op mOp;
|
||||
|
||||
typedef decltype(mOp.rootSteps(std::declval<intptr_t>()).extend( mExpr.rootSteps(std::declval<intptr_t>()) )) ExtType;
|
||||
ExtType mExt;
|
||||
|
||||
public:
|
||||
OpExpr(const OpExpr& in) = default;
|
||||
OpExpr(OpExpr&& in) = default;
|
||||
OpExpr& operator=(const OpExpr& in) = default;
|
||||
OpExpr& operator=(OpExpr&& in) = default;
|
||||
|
||||
OpExpr(const Op& mapf, const Index* ind, size_t step, Expr ex);
|
||||
|
||||
inline void operator()(size_t mlast, ExtType last);
|
||||
inline void operator()(size_t mlast = 0);
|
||||
|
||||
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
||||
|
||||
};
|
||||
|
||||
template <class OIType, class Op, SpaceType XSTYPE, class... Indices>
|
||||
class GenMapIndex : public IndexInterface<GenMapIndex<OIType,Op,XSTYPE,Indices...>,
|
||||
typename Op::value_type>
|
||||
//std::tuple<typename Indices::MetaType...> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef IndexInterface<GenMapIndex<OIType,Op,XSTYPE,Indices...>,
|
||||
typename Op::value_type> IB;
|
||||
//std::tuple<typename Indices::MetaType...> > IB;
|
||||
typedef std::tuple<std::shared_ptr<Indices>...> IndexPack;
|
||||
//typedef std::tuple<typename Indices::MetaType...> MetaType;
|
||||
typedef typename Op::value_type MetaType;
|
||||
typedef GenMapRange<typename OIType::RangeType,Op,XSTYPE,typename Indices::RangeType...> RangeType;
|
||||
typedef GenMapIndex IType;
|
||||
//typedef SingleIndex<typename Op::value_type,XSTYPE> OIType;
|
||||
|
||||
static constexpr IndexType sType() { return IndexType::SINGLE; }
|
||||
static constexpr size_t sDim() { return sizeof...(Indices); }
|
||||
static constexpr size_t totalDim() { return mkTotalDim<Indices...>(); }
|
||||
static void check_type() { static_assert( std::is_same<typename OIType::MetaType,typename Op::value_type>::value, "inconsitent value types" ); }
|
||||
|
||||
static constexpr SpaceType STYPE = XSTYPE;
|
||||
static constexpr bool PARALLEL = false;
|
||||
|
||||
private:
|
||||
|
||||
IndexPack mIPack;
|
||||
std::array<size_t,sizeof...(Indices)+1> mBlockSizes;
|
||||
std::shared_ptr<OIType> mOutIndex;
|
||||
|
||||
public:
|
||||
|
||||
const IndexPack& pack() const { return mIPack; }
|
||||
|
||||
GenMapIndex() = delete;
|
||||
|
||||
// NO DEFAULT HERE !!!
|
||||
// ( have to assign sub-indices (ptr!) correctly )
|
||||
//MapIndex(const MapIndex& in);
|
||||
//MapIndex& operator=(const MapIndex& in);
|
||||
|
||||
template <class MRange>
|
||||
GenMapIndex(const std::shared_ptr<MRange>& range);
|
||||
|
||||
template <size_t DIR>
|
||||
GenMapIndex& up();
|
||||
|
||||
template <size_t DIR>
|
||||
GenMapIndex& down();
|
||||
|
||||
template <size_t N>
|
||||
auto get() const -> decltype( *std::get<N>( mIPack ) )&;
|
||||
|
||||
template <size_t N>
|
||||
auto getPtr() const -> decltype( std::get<N>( mIPack ) )&;
|
||||
|
||||
template <size_t N>
|
||||
size_t getBlockSize() const { return std::get<N>(mBlockSizes); }
|
||||
|
||||
std::shared_ptr<OIType> outIndex() const;
|
||||
|
||||
// raplace instances (in contrast to its analogon in ContainerIndex
|
||||
// MultiIndices CANNOT be influences be its subindices, so there is
|
||||
// NO foreign/external controll)
|
||||
// Do NOT share index instances between two or more MapIndex instances
|
||||
GenMapIndex& operator()(const std::shared_ptr<Indices>&... indices);
|
||||
|
||||
// ==== >>>>> STATIC POLYMORPHISM <<<<< ====
|
||||
|
||||
IndexType type() const;
|
||||
|
||||
GenMapIndex& operator=(size_t pos);
|
||||
|
||||
GenMapIndex& operator++();
|
||||
GenMapIndex& operator--();
|
||||
|
||||
int pp(std::intptr_t idxPtrNum);
|
||||
int mm(std::intptr_t idxPtrNum);
|
||||
|
||||
std::string stringMeta() const;
|
||||
MetaType meta() const;
|
||||
GenMapIndex& at(const MetaType& metaPos);
|
||||
size_t posAt(const MetaType& metaPos) const;
|
||||
|
||||
size_t dim() const;
|
||||
bool first() const;
|
||||
bool last() const;
|
||||
std::shared_ptr<RangeType> range() const;
|
||||
|
||||
template <size_t N>
|
||||
auto getPtr() -> decltype( std::get<N>( mIPack ) )&;
|
||||
|
||||
size_t getStepSize(size_t n) const;
|
||||
|
||||
std::string id() const;
|
||||
void print(size_t offset) const;
|
||||
|
||||
template <class Exprs>
|
||||
auto ifor(size_t step, Exprs exs) const
|
||||
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh
|
||||
(step, mIPack, mBlockSizes, OpExpr<Op,GenMapIndex,Exprs,XSTYPE>( range()->map(), this, step, exs ) ) );
|
||||
// first step arg not used!
|
||||
|
||||
template <class Exprs>
|
||||
auto pifor(size_t step, Exprs exs) const
|
||||
-> decltype(ifor(step, exs)); // NO MULTITHREADING
|
||||
|
||||
|
||||
template <class Exprs>
|
||||
auto iforh(size_t step, Exprs exs) const
|
||||
-> decltype(ifor(step, exs));
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*************************
|
||||
* MapRangeFactory *
|
||||
*************************/
|
||||
|
||||
// NOT THREAD SAVE
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
class GenMapRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
public:
|
||||
//typedef SingleRange<typename Op::value_type,XSTYPE> ORType;
|
||||
typedef GenMapRange<ORType,Op,XSTYPE,Ranges...> oType;
|
||||
|
||||
GenMapRangeFactory() = delete;
|
||||
|
||||
template <class MA>
|
||||
GenMapRangeFactory(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
|
||||
const std::shared_ptr<Ranges>&... rs);
|
||||
|
||||
template <class MA>
|
||||
GenMapRangeFactory(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
|
||||
const typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::Space& st);
|
||||
|
||||
template <class MA>
|
||||
GenMapRangeFactory(const std::tuple<Op,MA>& mapf, const std::shared_ptr<Ranges>&... rs);
|
||||
|
||||
template <class MA>
|
||||
GenMapRangeFactory(const std::tuple<Op,MA>& mapf,
|
||||
const typename GenMapRange<ORType,Op,XSTYPE,Ranges...>::Space& space);
|
||||
|
||||
virtual std::shared_ptr<RangeBase> create() override;
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<RangeBase> checkIfCreated(const std::tuple<std::shared_ptr<Ranges>...>& ptp);
|
||||
|
||||
};
|
||||
|
||||
/******************
|
||||
* MapRange *
|
||||
******************/
|
||||
|
||||
template <class ORType, class Op, SpaceType XSTYPE, class... Ranges>
|
||||
class GenMapRange : public RangeInterface<GenMapIndex<typename ORType::IndexType,Op,XSTYPE,typename Ranges::IndexType...> >
|
||||
{
|
||||
public:
|
||||
typedef RangeBase RB;
|
||||
typedef std::tuple<std::shared_ptr<Ranges>...> Space;
|
||||
typedef GenMapIndex<typename ORType::IndexType,Op,XSTYPE,typename Ranges::IndexType...> IndexType;
|
||||
//typedef GenMapRange RangeType;
|
||||
//typedef SingleRange<typename Op::value_type,XSTYPE> ORType;
|
||||
//typedef SingleRangeFactory<typename Op::value_type,XSTYPE> ORFType;
|
||||
typedef typename Op::value_type MetaType;
|
||||
//typedef typename RangeInterface<MapIndex<typename Ranges::IndexType...> >::IndexType IndexType;
|
||||
|
||||
protected:
|
||||
GenMapRange() = delete;
|
||||
GenMapRange(const GenMapRange& in) = delete;
|
||||
GenMapRange& operator=(const GenMapRange& in) = delete;
|
||||
|
||||
template <class MA>
|
||||
GenMapRange(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
|
||||
const std::shared_ptr<Ranges>&... rs);
|
||||
|
||||
template <class MA>
|
||||
GenMapRange(const std::shared_ptr<ORType>& outr, const std::tuple<Op,MA>& mapf,
|
||||
const Space& space);
|
||||
|
||||
template <class MA>
|
||||
GenMapRange(const std::tuple<Op,MA>& mapf, const Space& space);
|
||||
|
||||
template <class MA>
|
||||
GenMapRange(const std::tuple<Op,MA>& mapf, const std::shared_ptr<Ranges>&... rs);
|
||||
|
||||
Space mSpace;
|
||||
Op mMapf;
|
||||
//Op mMapf;
|
||||
std::shared_ptr<ORType> mOutRange;
|
||||
MultiArray<size_t,ORType> mMapMult;
|
||||
vector<size_t> mMapPos;
|
||||
|
||||
private:
|
||||
template <class MA>
|
||||
void mkOutRange(const MA& mapf);
|
||||
|
||||
public:
|
||||
|
||||
static constexpr size_t sdim = sizeof...(Ranges);
|
||||
|
||||
template <size_t N>
|
||||
auto get() const -> decltype( *std::get<N>( mSpace ) )&;
|
||||
|
||||
template <size_t N>
|
||||
auto getPtr() const -> decltype( std::get<N>( mSpace ) )&;
|
||||
|
||||
std::shared_ptr<ORType> outRange() const;
|
||||
const Op& map() const;
|
||||
|
||||
virtual size_t dim() const final;
|
||||
virtual size_t size() const final;
|
||||
|
||||
virtual SpaceType spaceType() const final;
|
||||
virtual DataHeader dataHeader() const final;
|
||||
|
||||
virtual vector<size_t> typeNum() const final;
|
||||
virtual size_t cmeta(char* target, size_t pos) const final;
|
||||
virtual size_t cmetaSize() const final;
|
||||
virtual std::string stringMeta(size_t pos) const final;
|
||||
virtual vector<char> data() const final;
|
||||
|
||||
const Space& space() const;
|
||||
|
||||
virtual IndexType begin() const final;
|
||||
virtual IndexType end() const final;
|
||||
|
||||
const MultiArray<size_t,ORType>& mapMultiplicity() const;
|
||||
ConstSlice<size_t,GenMapRange> explMapMultiplicity() const;
|
||||
|
||||
vector<size_t> mapPos() const;
|
||||
|
||||
/*
|
||||
template <class... ERanges>
|
||||
auto cat(const std::shared_ptr<GenMapRange<ERanges...> >& erange)
|
||||
-> std::shared_ptr<GenMapRange<Ranges...,ERanges...> >;
|
||||
*/
|
||||
friend GenMapRangeFactory<ORType,Op,XSTYPE,Ranges...>;
|
||||
|
||||
static constexpr bool HASMETACONT = false;
|
||||
static constexpr bool defaultable = false;
|
||||
static constexpr size_t ISSTATIC = SubProp<Op,Ranges...>::ISSTATIC;
|
||||
static constexpr size_t SIZE = SubProp<Op,Ranges...>::SIZE;
|
||||
};
|
||||
|
||||
// for legacy
|
||||
template <class OIType, class Op, class... Indices>
|
||||
using MapIndex = GenMapIndex<OIType,Op,SpaceType::ANY,Indices...>;
|
||||
|
||||
template <class ORType, class Op, class... Ranges>
|
||||
using MapRangeFactory = GenMapRangeFactory<ORType,Op,SpaceType::ANY,Ranges...>;
|
||||
|
||||
template <class ORType, class Op, class... Ranges>
|
||||
using MapRange = GenMapRange<ORType,Op,SpaceType::ANY,Ranges...>;
|
||||
|
||||
template <class OIType, class Op, class... Indices>
|
||||
auto mapResult/*<MapIndex<Op,Indices...> >*/(const std::shared_ptr<MapIndex<OIType,Op,Indices...> >& ind)
|
||||
-> decltype(ind->outIndex())
|
||||
{
|
||||
return ind->outIndex();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
26
src/include/map_range_factory_product_map.h
Normal file
26
src/include/map_range_factory_product_map.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
#ifndef __map_range_factory_product_map_h__
|
||||
#define __map_range_factory_product_map_h__
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "ranges/rbase_def.h"
|
||||
#include "mbase_def.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
class MapRangeFactoryProductMap
|
||||
{
|
||||
public:
|
||||
|
||||
template <class ORType, class MapF, SpaceType XSTYPE, class... Ranges>
|
||||
friend class GenMapRangeFactory;
|
||||
|
||||
private:
|
||||
static std::map<std::shared_ptr<RangeBase>,vector<std::intptr_t> > mAleadyCreated;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
98
src/include/mbase_def.h
Normal file
98
src/include/mbase_def.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
|
||||
#ifndef __mbase_def_h__
|
||||
#define __mbase_def_h__
|
||||
|
||||
#include "ranges/rbase_def.h"
|
||||
#include "allocator.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
/***********************
|
||||
* Provided Types *
|
||||
***********************/
|
||||
|
||||
// multi_array.h
|
||||
template <typename T, class... SRanges>
|
||||
class MultiArrayBase;
|
||||
|
||||
// multi_array.h
|
||||
template <typename T, class... SRanges>
|
||||
class MutableMultiArrayBase;
|
||||
|
||||
// multi_array.h
|
||||
template <typename T, class... SRanges>
|
||||
class MultiArray;
|
||||
|
||||
// multi_array_operation.h
|
||||
template <typename T, class OperationClass>
|
||||
class OperationBase;
|
||||
|
||||
// multi_array_operation.h
|
||||
//template <typename T>
|
||||
//class MutableOperationBase;
|
||||
|
||||
// multi_array_operation.h
|
||||
template <typename T, class OperationClass>
|
||||
class OperationTemplate;
|
||||
|
||||
// multi_array_operation.h
|
||||
template <typename T, class... Ranges>
|
||||
class OperationRoot;
|
||||
|
||||
// multi_array_operation.h
|
||||
template <typename T, class... Ranges>
|
||||
class ParallelOperationRoot;
|
||||
|
||||
// multi_array_operation.h
|
||||
template <typename T>
|
||||
class OperationValue;
|
||||
|
||||
// multi_array_operation.h
|
||||
template <typename T, class... Ranges>
|
||||
class ConstOperationRoot;
|
||||
|
||||
// multi_array_operation.h
|
||||
template <typename T, class Op>
|
||||
class OperationPointer;
|
||||
|
||||
// multi_array_operation.h
|
||||
template <typename T, class OpFunction, class... Ops>
|
||||
class Operation;
|
||||
|
||||
// multi_array_operation.h
|
||||
template <typename T, class Op, class IndexType>
|
||||
class Contraction;
|
||||
|
||||
// multi_array_operation.h
|
||||
template <typename T, class Op, class... Indices>
|
||||
class SliceContraction;
|
||||
|
||||
// slice.h
|
||||
template <typename T, class... SRanges>
|
||||
class Slice;
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
class ConstSlice;
|
||||
|
||||
// slice.h
|
||||
template <typename T, class... SRanges>
|
||||
class SliceDef;
|
||||
|
||||
// slice.h
|
||||
template <typename T, class... SRanges>
|
||||
class ConstSliceDef;
|
||||
|
||||
// map_range.h
|
||||
template <class OITpye, class MapF, SpaceType XSTYPE, class... Indices>
|
||||
class GenMapIndex;
|
||||
|
||||
// map_range.h
|
||||
template <class ORType, class MapF, SpaceType XSTYPE, class... Ranges>
|
||||
class GenMapRangeFactory;
|
||||
|
||||
// map_range.h
|
||||
template <class ORType, class MapF, SpaceType XSTYPE, class... Ranges>
|
||||
class GenMapRange;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,56 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/memory/allocator.cc.h
|
||||
@brief Allocator template member function implementation
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_allocator_cc_h__
|
||||
#define __cxz_allocator_cc_h__
|
||||
|
||||
#include "allocator.h"
|
||||
#include "memcount.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
T* Allocator<T>::allocate(SizeT n)
|
||||
{
|
||||
const SizeT nn = n*type_size;
|
||||
MemCount::add(nn);
|
||||
const SizeT off = nn%N;
|
||||
const SizeT nnx = (off == 0) ? nn : nn + N - off;
|
||||
const SizeT nnd = nnx/N;
|
||||
VX* vx = new VX[nnd];
|
||||
return reinterpret_cast<T*>(vx);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Allocator<T>::deallocate(T* p, SizeT n)
|
||||
{
|
||||
const SizeT nn = n*type_size;
|
||||
MemCount::sub(nn);
|
||||
VX* vx = reinterpret_cast<VX*>(p);
|
||||
delete [] vx;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
bool operator==(const Allocator<T>& a, const Allocator<U>& b)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
bool operator!=(const Allocator<T>& a, const Allocator<U>& b)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,85 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/memory/allocator.h
|
||||
@brief Allocator declaration
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_allocator__
|
||||
#define __cxz_allocator__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include "base/types.h"
|
||||
#include "base/intrin.h"
|
||||
|
||||
#define MIB_SIZE 1024*1024 // 1MiB
|
||||
#define WARN_SIZE MIB_SIZE*100 // 100 MiB
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** *****
|
||||
Allocator implementation
|
||||
Takes care of proper alignment
|
||||
*/
|
||||
template <typename T>
|
||||
class Allocator
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
static constexpr SizeT type_size = sizeof(T); /** < type size */
|
||||
static constexpr SizeT N = MAX_VSIZE; /** < size of the larges available intrinsics vector */
|
||||
|
||||
/** ***
|
||||
Aligned data block type
|
||||
The size equals the maximal intrinsics vectors size
|
||||
*/
|
||||
struct VX
|
||||
{
|
||||
alignas(N) char x[N];
|
||||
};
|
||||
|
||||
/** default constructor */
|
||||
Allocator() = default;
|
||||
|
||||
/** (copy) construct from allocator for different data type
|
||||
@tparam U input data type
|
||||
@param x input allocator
|
||||
*/
|
||||
template <typename U>
|
||||
Allocator(const Allocator<U>& x) {}
|
||||
|
||||
/** allocate n element of type T
|
||||
@param n number of elements
|
||||
*/
|
||||
T* allocate(SizeT n);
|
||||
|
||||
/** deallocate n elements
|
||||
@param p pointer to first element
|
||||
@param n number of elements
|
||||
*/
|
||||
void deallocate(T* p, SizeT n);
|
||||
};
|
||||
|
||||
/** compare two cnorxz allocators; equality check returns always true */
|
||||
template <class T, class U>
|
||||
bool operator==(const Allocator<T>& a, const Allocator<U>& b);
|
||||
|
||||
/** compare two cnorxz allocators; unequality check returns always false */
|
||||
template <class T, class U>
|
||||
bool operator!=(const Allocator<T>& a, const Allocator<U>& b);
|
||||
|
||||
|
||||
} // namespace CNORXZ
|
||||
|
||||
#endif
|
|
@ -1,53 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/memory/memcount.h
|
||||
@brief MemCount declaration.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_memcount_h__
|
||||
#define __cxz_memcount_h__
|
||||
|
||||
#include "base/types.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** *****
|
||||
Static class to track memory usage by cnorxz types
|
||||
The usage variable can be changed only be an Allocator instance
|
||||
|
||||
@see Allocator
|
||||
**/
|
||||
class MemCount
|
||||
{
|
||||
private:
|
||||
static SizeT sMemUsage; /**< current memory usage (bytes) */
|
||||
|
||||
/** increas memory usage
|
||||
@param x number of bytes
|
||||
*/
|
||||
static void add(SizeT x);// { sMemUsage += x; }
|
||||
|
||||
/** decreas memory usage
|
||||
@param x number of bytes
|
||||
*/
|
||||
static void sub(SizeT x);// { sMemUsage -= x; }
|
||||
|
||||
public:
|
||||
/** no instance construction (static) */
|
||||
MemCount() = delete;
|
||||
|
||||
/** return current memory usage (bytes) */
|
||||
static SizeT usage();
|
||||
|
||||
template <typename T>
|
||||
friend class Allocator;
|
||||
};
|
||||
|
||||
} // namespace CNORXZ
|
||||
|
||||
#endif
|
|
@ -1,12 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/memory/memory.cc.h
|
||||
@brief Memory template implementations main header.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#include "allocator.cc.h"
|
|
@ -1,15 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/memory/memory.h
|
||||
@brief Memory main heade.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#include "allocator.h"
|
||||
#include "memcount.h"
|
||||
|
||||
#include "memory.cc.h"
|
307
src/include/multi_array.cc.h
Normal file
307
src/include/multi_array.cc.h
Normal file
|
@ -0,0 +1,307 @@
|
|||
|
||||
#include "multi_array.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
template <typename T>
|
||||
Scalar<T> scalar(const T& in)
|
||||
{
|
||||
NullRF nrf;
|
||||
return Scalar<T>( std::dynamic_pointer_cast<NullRange>( nrf.create() ), vector<T>( { in } ) );
|
||||
}
|
||||
|
||||
/*******************
|
||||
* MultiArray *
|
||||
*******************/
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>::MultiArray(const typename CRange::Space& space) :
|
||||
MutableMultiArrayBase<T,SRanges...>(space),
|
||||
mCont(MAB::mRange->size())
|
||||
{
|
||||
MAB::mInit = true;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>::MultiArray(const typename CRange::Space& space,
|
||||
const vector<T>& vec) :
|
||||
MutableMultiArrayBase<T,SRanges...>(space),
|
||||
mCont(vec)
|
||||
{
|
||||
MAB::mInit = true;
|
||||
if(mCont.size() > MAB::mRange->size()){
|
||||
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges) :
|
||||
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
||||
mCont(MAB::mRange->size())
|
||||
{
|
||||
MAB::mInit = true;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, const T& val) :
|
||||
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
||||
mCont(MAB::mRange->size(), val)
|
||||
{
|
||||
MAB::mInit = true;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, const vector<T>& vec) :
|
||||
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
||||
mCont(vec)
|
||||
{
|
||||
MAB::mInit = true;
|
||||
if(mCont.size() > MAB::mRange->size()){
|
||||
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, vector<T>&& vec) :
|
||||
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
||||
mCont(std::forward<vector<T>>(vec))
|
||||
{
|
||||
MAB::mInit = true;
|
||||
if(mCont.size() > MAB::mRange->size()){
|
||||
mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <class... Ranges>
|
||||
MultiArray<T,SRanges...>::MultiArray(const std::shared_ptr<SRanges>&... ranges, MultiArray<T,Ranges...>&& in) :
|
||||
MutableMultiArrayBase<T,SRanges...>(ranges...),
|
||||
mCont( std::move( in.mCont ) )
|
||||
{
|
||||
// maybe some checks here in the future...
|
||||
assert(mCont.size() == MAB::mRange->size());
|
||||
MAB::mInit = true;
|
||||
in.mInit = false;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>::MultiArray(MultiArray<T,AnonymousRange>&& ama, SIZET<SRanges>... sizes) :
|
||||
MutableMultiArrayBase<T,SRanges...>
|
||||
( ama.range()->template get<0>().template scast<SRanges...>(sizes...)->space() ),
|
||||
mCont( std::move( ama.mCont ) )
|
||||
{
|
||||
MAB::mInit = true;
|
||||
ama.mInit = false;
|
||||
}
|
||||
|
||||
/*
|
||||
template <typename T, class... SRanges>
|
||||
template <class Range2, class Range3>
|
||||
MultiArray<T,SRanges...>::MultiArray(const MultiArray<MultiArray<T,Range2>,Range3> in) :
|
||||
MutableMultiArrayBase<T,SRanges...>(merge(in.range(), in[ in.beginIndex() ].range()))
|
||||
// assert that Range2 has always same extension
|
||||
{
|
||||
MAB::mInit = true;
|
||||
mCont.clear();
|
||||
for(auto i = in.beginIndex(); i != in.endIndex(); ++i){
|
||||
mCont.insert(mCont.end(), in[i].mCont.begin(), in[i].mCont.end());
|
||||
}
|
||||
assert(mCont.size() == MAB::mRange->size());
|
||||
}
|
||||
*/
|
||||
/*
|
||||
template <typename T, class... SRanges>
|
||||
template <class Range2, class Range3>
|
||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator=(const MultiArray<MultiArray<T,Range2>,Range3> in)
|
||||
{
|
||||
MAB::mRange.reset(new Range(merge(in.range(), in[ in.beginIndex() ].range())));
|
||||
// assert that Range2 has always same extension
|
||||
mCont.clear();
|
||||
for(auto i = in.beginIndex(); i != in.endIndex(); ++i){
|
||||
mCont.insert(mCont.end(), in[i].mCont.begin(), in[i].mCont.end());
|
||||
}
|
||||
assert(mCont.size() == MAB::mRange->size());
|
||||
return *this;
|
||||
} */
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
T& MultiArray<T,SRanges...>::operator[](const IndexType& i)
|
||||
{
|
||||
return mCont[ i.pos() ];
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
const T& MultiArray<T,SRanges...>::operator[](const IndexType& i) const
|
||||
{
|
||||
return mCont[ i.pos() ];
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
T& MultiArray<T,SRanges...>::at(const typename IndexType::MetaType& meta)
|
||||
{
|
||||
return mCont[ MAB::beginIndex().at(meta).pos() ];
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
const T& MultiArray<T,SRanges...>::at(const typename IndexType::MetaType& meta) const
|
||||
{
|
||||
return mCont[ MAB::beginIndex().at(meta).pos() ];
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
bool MultiArray<T,SRanges...>::isConst() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
bool MultiArray<T,SRanges...>::isSlice() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <class... SRanges2>
|
||||
MultiArray<T,SRanges2...> MultiArray<T,SRanges...>::format(const std::shared_ptr<SRanges2>&... nrs)
|
||||
{
|
||||
//MAB::mInit = false;
|
||||
return MultiArray<T,SRanges2...>( nrs... , mCont );
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <class... SRanges2>
|
||||
MultiArray<T,SRanges2...> MultiArray<T,SRanges...>::format(const std::tuple<std::shared_ptr<SRanges2>...>& nrs)
|
||||
{
|
||||
//MAB::mInit = false;
|
||||
return MultiArray<T,SRanges2...>( nrs , mCont );
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <class... SRanges2>
|
||||
Slice<T,SRanges2...> MultiArray<T,SRanges...>::slformat(const std::shared_ptr<SRanges2>&... nrs)
|
||||
{
|
||||
return Slice<T,SRanges2...>( nrs..., mCont.data() );
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <class... SRanges2>
|
||||
ConstSlice<T,SRanges2...> MultiArray<T,SRanges...>::slformat(const std::shared_ptr<SRanges2>&... nrs) const
|
||||
{
|
||||
return ConstSlice<T,SRanges2...>( nrs..., mCont.data() );
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
const T* MultiArray<T,SRanges...>::data() const
|
||||
{
|
||||
return mCont.data();
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
T* MultiArray<T,SRanges...>::data()
|
||||
{
|
||||
return mCont.data();
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > MultiArray<T,SRanges...>::anonymous(bool slice) const
|
||||
{
|
||||
AnonymousRangeFactory arf(MAB::mRange->space());
|
||||
if(slice){
|
||||
return std::make_shared<ConstSlice<T,AnonymousRange> >
|
||||
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
|
||||
data() );
|
||||
}
|
||||
else {
|
||||
return std::make_shared<MultiArray<T,AnonymousRange> >
|
||||
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
|
||||
mCont );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
template <typename T, class... SRanges>
|
||||
std::shared_ptr<MultiArrayBase<T,AnonymousRange> > MultiArray<T,SRanges...>::anonymousMove()
|
||||
{
|
||||
AnonymousRangeFactory arf(MAB::mRange->space());
|
||||
MAB::mInit = false;
|
||||
return std::make_shared<MultiArray<T,AnonymousRange> >
|
||||
( std::dynamic_pointer_cast<AnonymousRange>( arf.create() ),
|
||||
std::move(mCont) );
|
||||
}
|
||||
*/
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator=(const T& in)
|
||||
{
|
||||
for(auto& x: mCont){
|
||||
x = in;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator+=(const MultiArray& in)
|
||||
{
|
||||
if(not MAB::mInit){ // not initialized by default constructor !!
|
||||
(*this) = in;
|
||||
}
|
||||
else {
|
||||
assert( PackNum<sizeof...(SRanges)-1>::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) );
|
||||
for(size_t i = 0; i != mCont.size(); ++i){
|
||||
mCont[i] += in.mCont[i];
|
||||
}
|
||||
//std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::plus<T>());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator-=(const MultiArray& in)
|
||||
{
|
||||
if(not MAB::mInit){ // not initialized by default constructor !!
|
||||
(*this) = in;
|
||||
}
|
||||
else {
|
||||
assert( PackNum<sizeof...(SRanges)-1>::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) );
|
||||
for(size_t i = 0; i != mCont.size(); ++i){
|
||||
mCont[i] -= in.mCont[i];
|
||||
}
|
||||
//std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::minus<T>());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator*=(const T& in)
|
||||
{
|
||||
for(auto& x: mCont){
|
||||
x *= in;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>& MultiArray<T,SRanges...>::operator/=(const T& in)
|
||||
{
|
||||
for(auto& x: mCont){
|
||||
x /= in;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArray<T,SRanges...>::operator T() const
|
||||
{
|
||||
//static_assert( sizeof...(SRanges) == 1, "try to cast non-scalar type into scalar" );
|
||||
// TODO: check that SIZE is statically = 1 !!!
|
||||
return mCont[0];
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
auto MultiArray<T,SRanges...>::cat() const
|
||||
-> decltype(ArrayCatter<T>::cat(*this))
|
||||
{
|
||||
return ArrayCatter<T>::cat(*this);
|
||||
}
|
||||
}
|
||||
|
151
src/include/multi_array.h
Normal file
151
src/include/multi_array.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
#ifndef __multi_array_h__
|
||||
#define __multi_array_h__
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "multi_array_base.h"
|
||||
#include "ranges/anonymous_range.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
template <typename T>
|
||||
struct ArrayCatter;
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct ArrayCatter
|
||||
{
|
||||
template <class... Ranges>
|
||||
static auto cat(const MultiArray<T,Ranges...>& ma)
|
||||
-> MultiArray<T,Ranges...>
|
||||
{
|
||||
return ma;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
class MultiArray : public MutableMultiArrayBase<T,SRanges...>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ContainerRange<T,SRanges...> CRange;
|
||||
typedef MultiArrayBase<T,SRanges...> MAB;
|
||||
typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType;
|
||||
|
||||
using MultiArrayBase<T,SRanges...>::operator[];
|
||||
using MutableMultiArrayBase<T,SRanges...>::operator[];
|
||||
|
||||
DEFAULT_MEMBERS(MultiArray);
|
||||
MultiArray(const std::shared_ptr<SRanges>&... ranges);
|
||||
MultiArray(const std::shared_ptr<SRanges>&... ranges, const T& val);
|
||||
MultiArray(const std::shared_ptr<SRanges>&... ranges, const vector<T>& vec);
|
||||
MultiArray(const std::shared_ptr<SRanges>&... ranges, vector<T>&& vec);
|
||||
|
||||
template <class... Ranges>
|
||||
MultiArray(const std::shared_ptr<SRanges>&... ranges, MultiArray<T,Ranges...>&& in); // same effect as format
|
||||
|
||||
MultiArray(const typename CRange::Space& space);
|
||||
MultiArray(const typename CRange::Space& space, const vector<T>& vec);
|
||||
MultiArray(MultiArray<T,AnonymousRange>&& ama, SIZET<SRanges>... sizes);
|
||||
|
||||
// Only if ALL ranges have default extensions:
|
||||
//MultiArray(const vector<T>& vec);
|
||||
//MultiArray(vector<T>&& vec);
|
||||
|
||||
// template <class Range2, class Range3>
|
||||
// MultiArray(const MultiArray<MultiArray<T,Range2>,Range3> in);
|
||||
|
||||
// implement contstructor using FunctionalMultiArray as Input !!!
|
||||
|
||||
//template <class Range2, class Range3>
|
||||
//MultiArray& operator=(const MultiArray<MultiArray<T,Range2>,Range3> in);
|
||||
|
||||
virtual T& operator[](const IndexType& i) final;
|
||||
virtual const T& operator[](const IndexType& i) const final;
|
||||
virtual T& at(const typename IndexType::MetaType& meta) override;
|
||||
virtual const T& at(const typename IndexType::MetaType& meta) const override;
|
||||
|
||||
virtual bool isConst() const override;
|
||||
virtual bool isSlice() const override;
|
||||
|
||||
template <class... SRanges2>
|
||||
MultiArray<T,SRanges2...> format(const std::shared_ptr<SRanges2>&... nrs); // reformat array using 'nr' which in
|
||||
// total must have the same size as mRange
|
||||
|
||||
template <class... SRanges2>
|
||||
MultiArray<T,SRanges2...> format(const std::tuple<std::shared_ptr<SRanges2>...>& nrs);
|
||||
|
||||
template <class... SRanges2>
|
||||
Slice<T,SRanges2...> slformat(const std::shared_ptr<SRanges2>&... nrs);
|
||||
|
||||
template <class... SRanges2>
|
||||
ConstSlice<T,SRanges2...> slformat(const std::shared_ptr<SRanges2>&... nrs) const;
|
||||
|
||||
virtual const T* data() const override;
|
||||
virtual T* data() override;
|
||||
virtual vector<T>& vdata() { return mCont; }
|
||||
virtual const vector<T>& vdata() const { return mCont; }
|
||||
vector<T>&& vmove() { MAB::mInit = false; return std::move(mCont); }
|
||||
|
||||
virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymous(bool slice = false) const override;
|
||||
//virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymousMove() override;
|
||||
|
||||
auto cat() const
|
||||
-> decltype(ArrayCatter<T>::cat(*this));
|
||||
|
||||
operator T() const;
|
||||
|
||||
MultiArray& operator=(const T& in);
|
||||
|
||||
MultiArray& operator+=(const MultiArray& in);
|
||||
MultiArray& operator-=(const MultiArray& in);
|
||||
MultiArray& operator*=(const T& in);
|
||||
MultiArray& operator/=(const T& in);
|
||||
|
||||
template <typename U, class... SRanges2>
|
||||
friend class MultiArray;
|
||||
|
||||
private:
|
||||
|
||||
vector<T> mCont;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using Scalar = MultiArray<T,NullRange>;
|
||||
|
||||
template <typename T>
|
||||
Scalar<T> scalar(const T& in);
|
||||
|
||||
template <typename T, class... ERanges>
|
||||
struct ArrayCatter<MultiArray<T,ERanges...> >
|
||||
{
|
||||
template <class... Ranges>
|
||||
static auto cat(const MultiArray<MultiArray<T,ERanges...>,Ranges...>& ma)
|
||||
-> MultiArray<T,Ranges...,ERanges...>
|
||||
{
|
||||
auto sma = *ma.begin();
|
||||
const size_t smas = sma.size();
|
||||
const size_t mas = ma.size();
|
||||
auto cr = ma.range()->cat(sma.range());
|
||||
vector<T> ov;
|
||||
ov.reserve(mas * smas);
|
||||
|
||||
for(auto& x: ma){
|
||||
assert(x.size() == smas);
|
||||
ov.insert(ov.end(), x.vdata().begin(), x.vdata().end());
|
||||
}
|
||||
return MultiArray<T,Ranges...,ERanges...>(cr->space(), std::move(ov));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* ========================= *
|
||||
* --- TEMPLATE CODE --- *
|
||||
* ========================= */
|
||||
|
||||
|
||||
#endif
|
281
src/include/multi_array_base.cc.h
Normal file
281
src/include/multi_array_base.cc.h
Normal file
|
@ -0,0 +1,281 @@
|
|||
|
||||
#include "multi_array_base.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
/**********************
|
||||
* MultiArrayBase *
|
||||
**********************/
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArrayBase<T,SRanges...>::MultiArrayBase(const MultiArrayBase& in) :
|
||||
mInit(in.mInit),
|
||||
mRange(in.mRange)
|
||||
{
|
||||
if(mRange){
|
||||
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArrayBase<T,SRanges...>::MultiArrayBase(MultiArrayBase&& in) :
|
||||
mInit(in.mInit),
|
||||
mRange(in.mRange)
|
||||
{
|
||||
if(mRange){
|
||||
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArrayBase<T,SRanges...>& MultiArrayBase<T,SRanges...>::operator=(const MultiArrayBase& in)
|
||||
{
|
||||
mInit = in.mInit;
|
||||
mRange = in.mRange;
|
||||
if(mRange){
|
||||
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArrayBase<T,SRanges...>& MultiArrayBase<T,SRanges...>::operator=(MultiArrayBase&& in)
|
||||
{
|
||||
mInit = in.mInit;
|
||||
mRange = in.mRange;
|
||||
if(mRange){
|
||||
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArrayBase<T,SRanges...>::MultiArrayBase(const std::shared_ptr<SRanges>&... ranges)
|
||||
{
|
||||
ContainerRangeFactory<T,SRanges...> crf(ranges...);
|
||||
mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() );
|
||||
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MultiArrayBase<T,SRanges...>::MultiArrayBase(const typename CRange::Space& space)
|
||||
{
|
||||
ContainerRangeFactory<T,SRanges...> crf(space);
|
||||
mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() );
|
||||
mProtoI = std::make_shared<IndexType>( mRange, reinterpret_cast<std::intptr_t>(this) );
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <typename X>
|
||||
const T& MultiArrayBase<T,SRanges...>::operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i)
|
||||
{
|
||||
IndexType ii(*mProtoI);
|
||||
ii = i;
|
||||
return (*this)[ii];
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
const T& MultiArrayBase<T,SRanges...>::operator[](const std::tuple<IPTR<typename SRanges::IndexType>...>& is) const
|
||||
{
|
||||
IndexType ii(*mProtoI);
|
||||
ii(is);
|
||||
return (*this)[ii];
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
size_t MultiArrayBase<T,SRanges...>::size() const
|
||||
{
|
||||
return mRange->size();
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::begin() const
|
||||
{
|
||||
IndexType i(*mProtoI,true);
|
||||
i = 0;
|
||||
return i.setData(data());
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::end() const
|
||||
{
|
||||
IndexType i(*mProtoI,true);
|
||||
i = i.max();
|
||||
//i = mRange->size();
|
||||
return i.setData(data());
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
typename MultiArrayBase<T,SRanges...>::IndexType
|
||||
MultiArrayBase<T,SRanges...>::beginIndex() const
|
||||
{
|
||||
IndexType i(*mProtoI,true);
|
||||
i = 0;
|
||||
return i.setData(data());
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
typename MultiArrayBase<T,SRanges...>::IndexType
|
||||
MultiArrayBase<T,SRanges...>::endIndex() const
|
||||
{
|
||||
IndexType i(*mProtoI,true);
|
||||
i = i.max();
|
||||
//i = mRange->size();
|
||||
return i.setData(data());
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
const std::shared_ptr<typename MultiArrayBase<T,SRanges...>::CRange>&
|
||||
MultiArrayBase<T,SRanges...>::range() const
|
||||
{
|
||||
return mRange;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
bool MultiArrayBase<T,SRanges...>::isConst() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
ConstOperationRoot<T,SRanges...>
|
||||
MultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
||||
{
|
||||
return ConstOperationRoot<T,SRanges...>(*this, inds...);
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
ConstOperationRoot<T,SRanges...>
|
||||
MultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind) const
|
||||
{
|
||||
return ConstOperationRoot<T,SRanges...>(data(), *ind);
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <class... MappedRanges>
|
||||
ConstOperationRoot<T,MappedRanges...>
|
||||
MultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const
|
||||
{
|
||||
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
||||
"number of mapped ranges must be equal to number of original ranges");
|
||||
return ConstOperationRoot<T,MappedRanges...>(*this, inds...);
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
bool MultiArrayBase<T,SRanges...>::isInit() const
|
||||
{
|
||||
return mInit;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <size_t N>
|
||||
auto MultiArrayBase<T,SRanges...>::getRangePtr() const
|
||||
-> decltype(mRange->template getPtr<N>())
|
||||
{
|
||||
return mRange->template getPtr<N>();
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
* MutableMultiArrayBase *
|
||||
******************************/
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges) :
|
||||
MultiArrayBase<T,SRanges...>(ranges...) {}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const typename CRange::Space& space) :
|
||||
MultiArrayBase<T,SRanges...>(space) {}
|
||||
/*
|
||||
template <typename T, class... SRanges>
|
||||
typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::begin()
|
||||
{
|
||||
auto i = mRange->begin();
|
||||
return i.setData(data());
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::end()
|
||||
{
|
||||
auto i = mRange->end();
|
||||
return i.setData(data());
|
||||
}
|
||||
*/
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <typename X>
|
||||
T& MutableMultiArrayBase<T,SRanges...>::operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i)
|
||||
{
|
||||
IndexType ii(*MAB::mProtoI);
|
||||
ii = i;
|
||||
return (*this)[ii];
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
T& MutableMultiArrayBase<T,SRanges...>::operator[](const std::tuple<IPTR<typename SRanges::IndexType>...>& is)
|
||||
{
|
||||
IndexType ii(*MAB::mProtoI);
|
||||
ii(is);
|
||||
return (*this)[ii];
|
||||
}
|
||||
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
bool MutableMultiArrayBase<T,SRanges...>::isConst() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
OperationRoot<T,SRanges...>
|
||||
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds)
|
||||
{
|
||||
return OperationRoot<T,SRanges...>(*this, inds...);
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
OperationRoot<T,SRanges...>
|
||||
MutableMultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind)
|
||||
{
|
||||
return OperationRoot<T,SRanges...>(data(), *ind);
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
ConstOperationRoot<T,SRanges...>
|
||||
MutableMultiArrayBase<T,SRanges...>::operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const
|
||||
{
|
||||
return ConstOperationRoot<T,SRanges...>(*this, inds...);
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
ConstOperationRoot<T,SRanges...>
|
||||
MutableMultiArrayBase<T,SRanges...>::op(const std::shared_ptr<IndexType>& ind) const
|
||||
{
|
||||
return ConstOperationRoot<T,SRanges...>(data(), *ind);
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <class... MappedRanges>
|
||||
OperationRoot<T,MappedRanges...>
|
||||
MutableMultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds)
|
||||
{
|
||||
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
||||
"number of mapped ranges must be equal to number of original ranges");
|
||||
return OperationRoot<T,MappedRanges...>(*this, inds...);
|
||||
}
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
template <class... MappedRanges>
|
||||
ConstOperationRoot<T,MappedRanges...>
|
||||
MutableMultiArrayBase<T,SRanges...>::m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const
|
||||
{
|
||||
static_assert(sizeof...(SRanges) == sizeof...(MappedRanges),
|
||||
"number of mapped ranges must be equal to number of original ranges");
|
||||
return ConstOperationRoot<T,MappedRanges...>(*this, inds...);
|
||||
}
|
||||
|
||||
} // end namespace MultiArrayTools
|
||||
|
187
src/include/multi_array_base.h
Normal file
187
src/include/multi_array_base.h
Normal file
|
@ -0,0 +1,187 @@
|
|||
|
||||
#ifndef __multi_array_base_h__
|
||||
#define __multi_array_base_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
#include "base_def.h"
|
||||
#include "mbase_def.h"
|
||||
|
||||
#include "ranges/rheader.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <class IndexType>
|
||||
using IPTR = std::shared_ptr<IndexType>;
|
||||
|
||||
template <class IndexType1, class IndexType2>
|
||||
inline auto operator|(const IPTR<IndexType1>& i1, const IPTR<IndexType2>& i2)
|
||||
-> decltype(std::make_tuple(i1,i2))
|
||||
{
|
||||
return std::make_tuple(i1,i2);
|
||||
}
|
||||
|
||||
template <class IndexType1, class... IndexTypes2>
|
||||
inline auto operator|(const IPTR<IndexType1>& i1,
|
||||
const std::tuple<IPTR<IndexTypes2>...>& i2)
|
||||
-> decltype(std::tuple_cat(std::make_tuple(i1),i2))
|
||||
{
|
||||
return std::tuple_cat(std::make_tuple(i1),i2);
|
||||
}
|
||||
|
||||
template <class IndexType2, class... IndexTypes1>
|
||||
inline auto operator|(const std::tuple<IPTR<IndexTypes1>...>& i1,
|
||||
const IPTR<IndexType2>& i2)
|
||||
-> decltype(std::tuple_cat(i1,std::make_tuple(i2)))
|
||||
{
|
||||
return std::tuple_cat(i1,std::make_tuple(i2));
|
||||
}
|
||||
|
||||
template <class IndexType>
|
||||
inline auto operator~(const IPTR<IndexType>& i)
|
||||
-> decltype(std::make_tuple(i))
|
||||
{
|
||||
return std::make_tuple(i);
|
||||
}
|
||||
|
||||
// Explicitely specify subranges in template argument !!!
|
||||
template <typename T, class... SRanges>
|
||||
class MultiArrayBase
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef ContainerRange<T,SRanges...> CRange;
|
||||
typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType;
|
||||
|
||||
protected:
|
||||
bool mInit = false;
|
||||
std::shared_ptr<CRange> mRange;
|
||||
std::shared_ptr<IndexType> mProtoI;
|
||||
|
||||
public:
|
||||
|
||||
//DEFAULT_MEMBERS(MultiArrayBase);
|
||||
MultiArrayBase(const std::shared_ptr<SRanges>&... ranges);
|
||||
MultiArrayBase(const typename CRange::Space& space);
|
||||
|
||||
MultiArrayBase() = default;
|
||||
MultiArrayBase(const MultiArrayBase& in);
|
||||
MultiArrayBase(MultiArrayBase&& in);
|
||||
MultiArrayBase& operator=(const MultiArrayBase& in);
|
||||
MultiArrayBase& operator=(MultiArrayBase&& in);
|
||||
|
||||
virtual ~MultiArrayBase() = default;
|
||||
|
||||
template <typename X>
|
||||
const T& operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i);
|
||||
const T& operator[](const std::tuple<IPTR<typename SRanges::IndexType>...>& is) const;
|
||||
|
||||
virtual const T& operator[](const IndexType& i) const = 0;
|
||||
virtual const T& at(const typename CRange::IndexType::MetaType& meta) const = 0;
|
||||
|
||||
virtual const T* data() const = 0;
|
||||
|
||||
virtual size_t size() const;
|
||||
virtual bool isSlice() const = 0;
|
||||
|
||||
virtual IndexType begin() const;
|
||||
virtual IndexType end() const;
|
||||
|
||||
virtual IndexType beginIndex() const;
|
||||
virtual IndexType endIndex() const;
|
||||
|
||||
virtual const std::shared_ptr<CRange>& range() const;
|
||||
|
||||
virtual bool isConst() const;
|
||||
|
||||
virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymous(bool slice = false) const = 0;
|
||||
|
||||
virtual ConstOperationRoot<T,SRanges...>
|
||||
op(const std::shared_ptr<IndexType>& ind) const;
|
||||
|
||||
virtual ConstOperationRoot<T,SRanges...>
|
||||
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const;
|
||||
|
||||
template <class... MappedRanges>
|
||||
ConstOperationRoot<T,MappedRanges...>
|
||||
m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const;
|
||||
|
||||
virtual bool isInit() const;
|
||||
|
||||
template <size_t N>
|
||||
auto getRangePtr() const
|
||||
-> decltype(mRange->template getPtr<N>());
|
||||
|
||||
};
|
||||
|
||||
template <typename T, class... SRanges>
|
||||
class MutableMultiArrayBase : public MultiArrayBase<T,SRanges...>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ContainerRange<T,SRanges...> CRange;
|
||||
typedef MultiArrayBase<T,SRanges...> MAB;
|
||||
typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType;
|
||||
|
||||
using MultiArrayBase<T,SRanges...>::operator[];
|
||||
using MultiArrayBase<T,SRanges...>::at;
|
||||
using MultiArrayBase<T,SRanges...>::data;
|
||||
using MultiArrayBase<T,SRanges...>::begin;
|
||||
using MultiArrayBase<T,SRanges...>::end;
|
||||
|
||||
DEFAULT_MEMBERS(MutableMultiArrayBase);
|
||||
MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges);
|
||||
MutableMultiArrayBase(const typename CRange::Space& space);
|
||||
|
||||
template <typename X>
|
||||
T& operator[](const ContainerIndex<X,typename SRanges::IndexType...>& i);
|
||||
T& operator[](const std::tuple<IPTR<typename SRanges::IndexType>...>& is);
|
||||
|
||||
virtual T& operator[](const IndexType& i) = 0;
|
||||
virtual T& at(const typename CRange::IndexType::MetaType& meta) = 0;
|
||||
|
||||
virtual T* data() = 0;
|
||||
|
||||
//virtual IndexType begin();
|
||||
//virtual IndexType end();
|
||||
|
||||
virtual bool isConst() const override;
|
||||
|
||||
//virtual std::shared_ptr<MultiArrayBase<T,AnonymousRange> > anonymousMove() = 0;
|
||||
|
||||
virtual ConstOperationRoot<T,SRanges...>
|
||||
op(const std::shared_ptr<IndexType>& ind) const override;
|
||||
|
||||
virtual ConstOperationRoot<T,SRanges...>
|
||||
operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const override;
|
||||
|
||||
virtual OperationRoot<T,SRanges...>
|
||||
op(const std::shared_ptr<IndexType>& ind);
|
||||
|
||||
virtual OperationRoot<T,SRanges...> operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds);
|
||||
|
||||
template <class... MappedRanges>
|
||||
OperationRoot<T,MappedRanges...>
|
||||
m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds);
|
||||
|
||||
template <class... MappedRanges>
|
||||
ConstOperationRoot<T,MappedRanges...>
|
||||
m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // end namespace MultiArrayTools
|
||||
|
||||
/* ========================= *
|
||||
* --- TEMPLATE CODE --- *
|
||||
* ========================= */
|
||||
|
||||
|
||||
#endif
|
14
src/include/multi_array_header.cc.h
Normal file
14
src/include/multi_array_header.cc.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
#include "ranges/ranges_header.cc.h"
|
||||
|
||||
#include "multi_array_operation.cc.h"
|
||||
#include "functional_multi_array.cc.h"
|
||||
#include "helper_tools.cc.h"
|
||||
#include "map_range.cc.h"
|
||||
#include "multi_array_base.cc.h"
|
||||
#include "multi_array.cc.h"
|
||||
#include "slice.cc.h"
|
||||
#include "dynamic_operation.cc.h"
|
||||
#include "high_level_operation.cc.h"
|
||||
//#include "expressions.cc.h"
|
||||
|
20
src/include/multi_array_header.h
Normal file
20
src/include/multi_array_header.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
#ifndef __multi_array_header_h__
|
||||
#define __multi_array_header_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include "multi_array_operation.h"
|
||||
#include "multi_array_base.h"
|
||||
#include "multi_array.h"
|
||||
#include "functional_multi_array.h"
|
||||
#include "helper_tools.h"
|
||||
#include "operation_def.h"
|
||||
#include "map_range.h"
|
||||
#include "dynamic_operation.h"
|
||||
#include "high_level_operation.h"
|
||||
//#include "expressions.h"
|
||||
|
||||
#include "multi_array_header.cc.h"
|
||||
|
||||
#endif
|
1025
src/include/multi_array_operation.cc.h
Normal file
1025
src/include/multi_array_operation.cc.h
Normal file
File diff suppressed because it is too large
Load diff
851
src/include/multi_array_operation.h
Normal file
851
src/include/multi_array_operation.h
Normal file
|
@ -0,0 +1,851 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
#ifndef __multi_array_operation_h__
|
||||
#define __multi_array_operation_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <tuple>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "base_def.h"
|
||||
#include "mbase_def.h"
|
||||
|
||||
#include "ranges/rheader.h"
|
||||
#include "pack_num.h"
|
||||
|
||||
#include "arith.h"
|
||||
|
||||
#include "xfor/xfor.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace MultiArrayHelper;
|
||||
}
|
||||
|
||||
template <typename T, class OperationClass>
|
||||
class OperationBase
|
||||
{
|
||||
public:
|
||||
|
||||
OperationClass& THIS() { return static_cast<OperationClass&>(*this); }
|
||||
const OperationClass& THIS() const { return static_cast<OperationClass const&>(*this); }
|
||||
|
||||
template <typename U, class Second>
|
||||
auto operator+(const OperationBase<U,Second>& in) const;
|
||||
|
||||
template <typename U, class Second>
|
||||
auto operator-(const OperationBase<U,Second>& in) const;
|
||||
|
||||
template <typename U, class Second>
|
||||
auto operator*(const OperationBase<U,Second>& in) const;
|
||||
|
||||
template <typename U, class Second>
|
||||
auto operator/(const OperationBase<U,Second>& in) const;
|
||||
|
||||
template <class IndexType>
|
||||
auto c(const std::shared_ptr<IndexType>& ind) const
|
||||
-> Contraction<T,OperationClass,IndexType>;
|
||||
|
||||
template <class... Indices>
|
||||
auto sl(const std::shared_ptr<Indices>&... inds) const
|
||||
-> ConstSlice<T,typename Indices::RangeType...>;
|
||||
|
||||
template <class... Indices>
|
||||
auto slc(const std::shared_ptr<Indices>&... inds) const
|
||||
-> SliceContraction<T,OperationClass,Indices...>;
|
||||
|
||||
template <class... Indices>
|
||||
auto p(const std::shared_ptr<Indices>&... inds) const
|
||||
-> ConstOperationRoot<T,typename Indices::RangeType...>;
|
||||
|
||||
template <class... Indices>
|
||||
auto to(const std::shared_ptr<Indices>&... inds) const
|
||||
-> MultiArray<T,typename Indices::RangeType...>;
|
||||
|
||||
template <class... Indices>
|
||||
auto addto(const std::shared_ptr<Indices>&... inds) const
|
||||
-> MultiArray<T,typename Indices::RangeType...>;
|
||||
|
||||
template <class... Indices>
|
||||
auto pto(const std::shared_ptr<Indices>&... inds) const
|
||||
-> MultiArray<T,typename Indices::RangeType...>;
|
||||
|
||||
template <class... Indices>
|
||||
auto paddto(const std::shared_ptr<Indices>&... inds) const
|
||||
-> MultiArray<T,typename Indices::RangeType...>;
|
||||
|
||||
template <typename R, class... Args> // Args = Operation Classes
|
||||
auto a(const std::shared_ptr<function<R,T,typename Args::value_type...>>& ll, const Args&... args) const
|
||||
-> Operation<R,function<R,T,typename Args::value_type...>,OperationClass, Args...>;
|
||||
|
||||
auto ptr() const
|
||||
-> OperationPointer<T,OperationClass>;
|
||||
|
||||
private:
|
||||
friend OperationClass;
|
||||
friend OperationTemplate<T,OperationClass>;
|
||||
OperationBase() = default;
|
||||
};
|
||||
|
||||
template <typename T, class OperationClass>
|
||||
class OperationTemplate : public OperationBase<T,OperationClass>
|
||||
{
|
||||
/* empty per default; specialize if needed */
|
||||
private:
|
||||
OperationTemplate() = default;
|
||||
friend OperationClass;
|
||||
};
|
||||
|
||||
template <class Op>
|
||||
size_t sumRootNum()
|
||||
{
|
||||
return typename Op::rootNum();
|
||||
}
|
||||
|
||||
template <class Op1, class Op2, class... Ops>
|
||||
size_t sumRootNum()
|
||||
{
|
||||
return typename Op1::rootNum() + sumRootNum<Op2,Ops...>();
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
struct RootSumN
|
||||
{
|
||||
template <class Op1, class... Ops>
|
||||
struct rs
|
||||
{
|
||||
static constexpr size_t SIZE = Op1::SIZE + RootSumN<N-1>::template rs<Ops...>::SIZE;
|
||||
};
|
||||
|
||||
template <class... Exprs>
|
||||
static inline auto rootSteps(const std::tuple<Exprs...>& etp, std::intptr_t i)
|
||||
{
|
||||
return RootSumN<N-1>::rootSteps(etp,i).extend( std::get<N>(etp).rootSteps(i) );
|
||||
}
|
||||
|
||||
template <class ExtType, class... Exprs>
|
||||
static inline void exec( size_t start, ExtType last, std::tuple<Exprs...>& etp)
|
||||
{
|
||||
std::get<sizeof...(Exprs)-N-1>(etp)(start,last);
|
||||
RootSumN<N-1>::exec(start,last.next(),etp);
|
||||
}
|
||||
|
||||
template <class ExtType, class... Exprs>
|
||||
static inline size_t get( ExtType last, const std::tuple<Exprs...>& etp)
|
||||
{
|
||||
std::get<sizeof...(Exprs)-N-1>(etp).get(last);
|
||||
return RootSumN<N-1>::get(last.next(),etp);
|
||||
}
|
||||
|
||||
template <class ExtType, class... Exprs>
|
||||
static inline void set( ExtType last, std::tuple<Exprs...>& etp)
|
||||
{
|
||||
std::get<sizeof...(Exprs)-N-1>(etp).set(last);
|
||||
RootSumN<N-1>::set(last.next(),etp);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct RootSumN<0>
|
||||
{
|
||||
template <class Op1>
|
||||
struct rs
|
||||
{
|
||||
static constexpr size_t SIZE = Op1::SIZE;
|
||||
};
|
||||
|
||||
template <class... Exprs>
|
||||
static inline auto rootSteps(const std::tuple<Exprs...>& etp, std::intptr_t i)
|
||||
{
|
||||
return std::get<0>(etp).rootSteps(i);
|
||||
}
|
||||
|
||||
template <class ExtType, class... Exprs>
|
||||
static inline void exec( size_t start, ExtType last, std::tuple<Exprs...>& etp)
|
||||
{
|
||||
std::get<sizeof...(Exprs)-1>(etp)(start,last);
|
||||
}
|
||||
|
||||
template <class ExtType, class... Exprs>
|
||||
static inline size_t get( ExtType last, const std::tuple<Exprs...>& etp)
|
||||
{
|
||||
std::get<sizeof...(Exprs)-1>(etp).get(last);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class ExtType, class... Exprs>
|
||||
static inline void set( ExtType last, std::tuple<Exprs...>& etp)
|
||||
{
|
||||
std::get<sizeof...(Exprs)-1>(etp).set(last);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class... Ops>
|
||||
struct RootSum
|
||||
{
|
||||
static constexpr size_t SIZE = RootSumN<sizeof...(Ops)-1>::template rs<Ops...>::SIZE;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct SelfIdentity
|
||||
{
|
||||
static inline T& sapply(T& a, T b)
|
||||
{
|
||||
return a = b;
|
||||
}
|
||||
};
|
||||
|
||||
enum class OpIndexAff {
|
||||
EXTERN = 0,
|
||||
TARGET = 1
|
||||
};
|
||||
|
||||
template <typename T, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
|
||||
class AssignmentExpr2 : public ExpressionBase
|
||||
{
|
||||
private:
|
||||
AssignmentExpr2() = default;
|
||||
|
||||
Target mTar;
|
||||
OpClass mSec;
|
||||
T* mDataPtr;
|
||||
|
||||
public:
|
||||
|
||||
static constexpr size_t LAYER = 0;
|
||||
static constexpr size_t SIZE = Target::SIZE + OpClass::SIZE;
|
||||
typedef decltype(mTar.rootSteps(0).extend( mSec.rootSteps(0) )) ExtType;
|
||||
|
||||
AssignmentExpr2(T* dataPtr, const Target& tar, const OpClass& sec);
|
||||
AssignmentExpr2(const AssignmentExpr2& in) = default;
|
||||
AssignmentExpr2(AssignmentExpr2&& in) = default;
|
||||
AssignmentExpr2& operator=(const AssignmentExpr2& in) = default;
|
||||
AssignmentExpr2& operator=(AssignmentExpr2&& in) = default;
|
||||
|
||||
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
|
||||
{
|
||||
return std::make_shared<AssignmentExpr2<T,Target,OpClass,OIA>>(*this);
|
||||
}
|
||||
|
||||
inline void operator()(size_t start = 0);
|
||||
inline void operator()(size_t start, ExtType last);
|
||||
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
||||
|
||||
inline void operator()(size_t mlast, DExt last) override final;
|
||||
|
||||
inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
|
||||
inline DExt dExtension() const override final;
|
||||
};
|
||||
|
||||
template <typename T, class... Ops>
|
||||
class MOp
|
||||
{
|
||||
private:
|
||||
MOp() = default;
|
||||
std::tuple<Ops...> mOps;
|
||||
|
||||
public:
|
||||
static constexpr size_t LAYER = 0;
|
||||
static constexpr size_t SIZE = RootSum<Ops...>::SIZE;
|
||||
typedef decltype(RootSumN<sizeof...(Ops)-1>::rootSteps(mOps,0) ) ExtType;
|
||||
|
||||
MOp(const Ops&... exprs);
|
||||
|
||||
MOp(const MOp& in) = default;
|
||||
MOp(MOp&& in) = default;
|
||||
MOp& operator=(const MOp& in) = default;
|
||||
MOp& operator=(MOp&& in) = default;
|
||||
|
||||
inline size_t get(ExtType last) const;
|
||||
inline MOp& set(ExtType last);
|
||||
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
||||
|
||||
template <class Expr>
|
||||
auto loop(Expr exp) const
|
||||
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp));
|
||||
|
||||
T* data() const { assert(0); return nullptr; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <class OpClass, class NextExpr>
|
||||
class GetExpr : public ExpressionBase
|
||||
{
|
||||
private:
|
||||
GetExpr() = default;
|
||||
|
||||
OpClass mSec;
|
||||
NextExpr mNExpr;
|
||||
|
||||
public:
|
||||
|
||||
static constexpr size_t LAYER = 0;
|
||||
static constexpr size_t SIZE = OpClass::SIZE + NextExpr::SIZE;
|
||||
typedef decltype(mSec.rootSteps(0).extend( mNExpr.rootSteps(0) ) ) ExtType;
|
||||
|
||||
GetExpr(const OpClass& sec, const NextExpr& nexpr);
|
||||
GetExpr(const GetExpr& in) = default;
|
||||
GetExpr(GetExpr&& in) = default;
|
||||
GetExpr& operator=(const GetExpr& in) = default;
|
||||
GetExpr& operator=(GetExpr&& in) = default;
|
||||
|
||||
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
|
||||
{
|
||||
return std::make_shared<GetExpr<OpClass,NextExpr>>(*this);
|
||||
}
|
||||
|
||||
inline void operator()(size_t start = 0);
|
||||
inline void get(ExtType last);
|
||||
inline void operator()(size_t start, ExtType last);
|
||||
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
||||
|
||||
inline void operator()(size_t mlast, DExt last) override final;
|
||||
|
||||
inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
|
||||
inline DExt dExtension() const override final;
|
||||
};
|
||||
|
||||
template <class OpClass, class NextExpr>
|
||||
auto mkGetExpr(const OpClass& op, const NextExpr& nexpr)
|
||||
{
|
||||
return GetExpr<OpClass,NextExpr>(op, nexpr);
|
||||
}
|
||||
|
||||
template <typename T, class... Ops>
|
||||
auto mkMOp(const Ops&... exprs)
|
||||
{
|
||||
return MOp<T,Ops...>(exprs...);
|
||||
}
|
||||
|
||||
//template <typename T, class OpClass>
|
||||
template <typename T, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
|
||||
class AddExpr : public ExpressionBase
|
||||
{
|
||||
private:
|
||||
AddExpr() = default;
|
||||
|
||||
Target mTar;
|
||||
OpClass mSec;
|
||||
T* mDataPtr;
|
||||
|
||||
public:
|
||||
|
||||
static constexpr size_t LAYER = 0;
|
||||
static constexpr size_t SIZE = Target::SIZE + OpClass::SIZE;
|
||||
typedef decltype(mTar.rootSteps(0).extend( mSec.rootSteps(0) )) ExtType;
|
||||
// static constexpr size_t LAYER = 0;
|
||||
//static constexpr size_t SIZE = OpClass::SIZE;
|
||||
//typedef decltype(mSec.rootSteps()) ExtType;
|
||||
|
||||
//AddExpr(T* dataPtr, const OpClass& sec);
|
||||
AddExpr(T* dataPtr, const Target& tar, const OpClass& sec);
|
||||
AddExpr(const AddExpr& in) = default;
|
||||
AddExpr(AddExpr&& in) = default;
|
||||
AddExpr& operator=(const AddExpr& in) = default;
|
||||
AddExpr& operator=(AddExpr&& in) = default;
|
||||
|
||||
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
|
||||
{
|
||||
return std::make_shared<AddExpr<T,Target,OpClass,OIA>>(*this);
|
||||
}
|
||||
|
||||
inline void operator()(size_t start = 0);
|
||||
inline void operator()(size_t start, ExtType last);
|
||||
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
||||
|
||||
inline void operator()(size_t mlast, DExt last) override final;
|
||||
|
||||
inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
|
||||
inline DExt dExtension() const override final;
|
||||
};
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
class ConstOperationRoot : public OperationTemplate<T,ConstOperationRoot<T,Ranges...> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef OperationBase<T,ConstOperationRoot<T,Ranges...> > OT;
|
||||
typedef ContainerRange<T,Ranges...> CRange;
|
||||
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
||||
|
||||
static constexpr size_t SIZE = 1;
|
||||
static constexpr bool CONT = true;
|
||||
|
||||
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
|
||||
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
||||
|
||||
ConstOperationRoot(std::shared_ptr<MultiArrayBase<T,Ranges...> > maptr,
|
||||
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
||||
|
||||
ConstOperationRoot(const T* data, const IndexType& ind);
|
||||
|
||||
template <class ET>
|
||||
inline const T& get(ET pos) const;
|
||||
|
||||
template <class ET>
|
||||
inline ConstOperationRoot& set(ET pos);
|
||||
|
||||
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
||||
|
||||
template <class Expr>
|
||||
Expr loop(Expr exp) const;
|
||||
|
||||
const T* data() const;
|
||||
|
||||
private:
|
||||
|
||||
const T* mDataPtr;
|
||||
const T* mOrigDataPtr;
|
||||
IndexType mIndex;
|
||||
std::shared_ptr<MultiArrayBase<T,Ranges...> > mMaPtr; // never remove this ptr, otherwise we lose temporary container instances!
|
||||
};
|
||||
|
||||
template <typename T, class Op>
|
||||
class StaticCast : public OperationTemplate<T,StaticCast<T,Op> >
|
||||
{
|
||||
private:
|
||||
Op mOp;
|
||||
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef OperationBase<T,StaticCast<T,Op> > OT;
|
||||
typedef typename Op::CRange CRange;
|
||||
typedef typename Op::IndexType IndexType;
|
||||
|
||||
static constexpr size_t SIZE = Op::SIZE;
|
||||
static constexpr bool CONT = false;
|
||||
|
||||
StaticCast(const Op& op);
|
||||
|
||||
template <class ET>
|
||||
inline T get(ET pos) const;
|
||||
|
||||
template <class ET>
|
||||
inline StaticCast& set(ET pos);
|
||||
|
||||
auto rootSteps(std::intptr_t iPtrNum = 0) const
|
||||
-> decltype(mOp.rootSteps(iPtrNum));
|
||||
|
||||
template <class Expr>
|
||||
Expr loop(Expr exp) const;
|
||||
|
||||
};
|
||||
|
||||
template <typename T, class Op>
|
||||
StaticCast<T,Op> staticcast(const Op& op)
|
||||
{
|
||||
return StaticCast<T,Op>(op);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
class MetaOperationRoot : public OperationTemplate<typename Range::MetaType,
|
||||
MetaOperationRoot<Range> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename Range::IndexType IndexType;
|
||||
typedef typename IndexType::MetaType value_type;
|
||||
typedef OperationBase<value_type,MetaOperationRoot<Range> > OT;
|
||||
|
||||
static constexpr size_t SIZE = 1;
|
||||
static constexpr bool CONT = false;
|
||||
|
||||
MetaOperationRoot(const std::shared_ptr<IndexType>& ind);
|
||||
|
||||
template <class ET>
|
||||
inline value_type get(ET pos) const;
|
||||
|
||||
template <class ET>
|
||||
inline MetaOperationRoot& set(ET pos);
|
||||
|
||||
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
||||
|
||||
template <class Expr>
|
||||
Expr loop(Expr exp) const;
|
||||
|
||||
private:
|
||||
|
||||
mutable IndexType mWorkIndex;
|
||||
std::shared_ptr<IndexType> mIndex;
|
||||
};
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
class OperationRoot : public OperationTemplate<T,OperationRoot<T,Ranges...> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef OperationBase<T,OperationRoot<T,Ranges...> > OT;
|
||||
typedef ContainerRange<T,Ranges...> CRange;
|
||||
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
||||
|
||||
static constexpr size_t SIZE = 1;
|
||||
static constexpr bool CONT = true;
|
||||
|
||||
private:
|
||||
|
||||
T* mDataPtr;
|
||||
T* mOrigDataPtr;
|
||||
IndexType mIndex;
|
||||
|
||||
public:
|
||||
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
||||
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
||||
|
||||
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
||||
const std::tuple<std::shared_ptr<typename Ranges::IndexType>...>& indices);
|
||||
|
||||
OperationRoot(T* data, const IndexType& ind);
|
||||
|
||||
template <class OpClass>
|
||||
auto assign(const OpClass& in) const
|
||||
-> decltype(mIndex.ifor(1,in.loop(AssignmentExpr2<T,OperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
|
||||
(mOrigDataPtr,*this,in))));
|
||||
|
||||
template <class OpClass>
|
||||
auto assignExpr(const OpClass& in) const
|
||||
-> decltype(in.loop(AssignmentExpr2<T,OperationRoot<T,Ranges...>,OpClass>(mOrigDataPtr,*this,in)));
|
||||
|
||||
template <class OpClass, class Index>
|
||||
auto assign(const OpClass& in, const std::shared_ptr<Index>& i) const
|
||||
-> decltype(i->ifor(1,in.loop(AssignmentExpr2<T,OperationRoot<T,Ranges...>,OpClass>
|
||||
(mOrigDataPtr,*this,in))));
|
||||
|
||||
template <class OpClass>
|
||||
auto plus(const OpClass& in) const
|
||||
-> decltype(mIndex.ifor(1,in.loop(AddExpr<T,OperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
|
||||
(mOrigDataPtr,*this,in))));
|
||||
|
||||
template <class OpClass, class Index>
|
||||
auto plus(const OpClass& in, const std::shared_ptr<Index>& i) const
|
||||
-> decltype(i->ifor(1,in.loop(AddExpr<T,OperationRoot<T,Ranges...>,OpClass>
|
||||
(mOrigDataPtr,*this,in))));
|
||||
|
||||
template <class OpClass>
|
||||
OperationRoot& operator=(const OpClass& in);
|
||||
|
||||
template <class OpClass>
|
||||
OperationRoot& operator+=(const OpClass& in);
|
||||
|
||||
OperationRoot& operator=(const OperationRoot& in);
|
||||
|
||||
ParallelOperationRoot<T,Ranges...> par();
|
||||
|
||||
template <class ET>
|
||||
inline T& get(ET pos) const;
|
||||
|
||||
template <class ET>
|
||||
inline OperationRoot& set(ET pos);
|
||||
|
||||
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
||||
|
||||
template <class Expr>
|
||||
Expr loop(Expr exp) const;
|
||||
|
||||
T* data() const;
|
||||
|
||||
template <class... Indices>
|
||||
auto sl(const std::shared_ptr<Indices>&... inds)
|
||||
-> Slice<T,typename Indices::RangeType...>;
|
||||
|
||||
};
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
class ParallelOperationRoot : public OperationTemplate<T,ParallelOperationRoot<T,Ranges...> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef OperationBase<T,ParallelOperationRoot<T,Ranges...> > OT;
|
||||
typedef ContainerRange<T,Ranges...> CRange;
|
||||
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
||||
|
||||
static constexpr size_t SIZE = 1;
|
||||
static constexpr bool CONT = true;
|
||||
|
||||
private:
|
||||
|
||||
T* mDataPtr;
|
||||
T* mOrigDataPtr;
|
||||
IndexType mIndex;
|
||||
|
||||
public:
|
||||
ParallelOperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
||||
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
||||
|
||||
ParallelOperationRoot(T* data, const IndexType& ind);
|
||||
|
||||
template <class OpClass>
|
||||
auto assign(const OpClass& in)
|
||||
-> decltype(mIndex.pifor(1,in.loop(AssignmentExpr2<T,ParallelOperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
|
||||
(mOrigDataPtr,*this,in))));
|
||||
|
||||
template <class OpClass, class Index>
|
||||
auto assign(const OpClass& in, const std::shared_ptr<Index>& i) const
|
||||
-> decltype(i->pifor(1,in.loop(AssignmentExpr2<T,ParallelOperationRoot<T,Ranges...>,OpClass>
|
||||
(mOrigDataPtr,*this,in))));
|
||||
|
||||
template <class OpClass>
|
||||
auto plus(const OpClass& in)
|
||||
-> decltype(mIndex.pifor(1,in.loop(AddExpr<T,ParallelOperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
|
||||
(mOrigDataPtr,*this,in))));
|
||||
|
||||
template <class OpClass, class Index>
|
||||
auto plus(const OpClass& in, const std::shared_ptr<Index>& i) const
|
||||
-> decltype(i->pifor(1,in.loop(AddExpr<T,ParallelOperationRoot<T,Ranges...>,OpClass>
|
||||
(mOrigDataPtr,*this,in))));
|
||||
|
||||
template <class OpClass>
|
||||
ParallelOperationRoot& operator=(const OpClass& in);
|
||||
|
||||
template <class OpClass>
|
||||
ParallelOperationRoot& operator+=(const OpClass& in);
|
||||
|
||||
ParallelOperationRoot& operator=(const ParallelOperationRoot& in);
|
||||
|
||||
template <class ET>
|
||||
inline T& get(ET pos) const;
|
||||
|
||||
template <class ET>
|
||||
inline ParallelOperationRoot& set(ET pos);
|
||||
|
||||
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
||||
|
||||
template <class Expr>
|
||||
Expr loop(Expr exp) const;
|
||||
|
||||
T* data() const;
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class OperationValue : public OperationTemplate<T,OperationValue<T> >
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef OperationBase<T,OperationValue<T> > OT;
|
||||
typedef ContainerRange<T,NullRange> CRange;
|
||||
typedef ContainerIndex<T,NullIndex> IndexType;
|
||||
|
||||
static constexpr size_t SIZE = 0;
|
||||
static constexpr bool CONT = true;
|
||||
|
||||
OperationValue(const T& val);
|
||||
|
||||
template <class ET>
|
||||
inline const T& get(ET pos) const;
|
||||
|
||||
template <class ET>
|
||||
inline OperationValue& set(ET pos);
|
||||
|
||||
None rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
||||
|
||||
template <class Expr>
|
||||
Expr loop(Expr exp) const;
|
||||
|
||||
private:
|
||||
T mVal;
|
||||
};
|
||||
|
||||
template <typename T, class Op>
|
||||
class OperationPointer : public OperationTemplate<const T*,OperationPointer<T,Op>>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef OperationTemplate<const T*,OperationPointer<T,Op>> OT;
|
||||
|
||||
static constexpr size_t SIZE = Op::SIZE;
|
||||
static constexpr bool CONT = false;
|
||||
|
||||
private:
|
||||
Op mOp;
|
||||
|
||||
public:
|
||||
|
||||
OperationPointer(const Op& op) : mOp(op)
|
||||
{
|
||||
static_assert(Op::CONT,
|
||||
"OperationPointer can only be applied to containing operations");
|
||||
}
|
||||
|
||||
template <class ET>
|
||||
inline const T* get(ET pos) const;
|
||||
|
||||
template <class ET>
|
||||
inline OperationPointer& set(ET pos);
|
||||
|
||||
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
||||
-> decltype(mOp.rootSteps(0));
|
||||
|
||||
template <class Expr>
|
||||
auto loop(Expr exp) const
|
||||
-> decltype(mOp.loop(exp));
|
||||
|
||||
T const** data() const { assert(0); return nullptr; }
|
||||
};
|
||||
|
||||
template <typename T, class OpFunction, class... Ops>
|
||||
class Operation : public OperationTemplate<T,Operation<T,OpFunction,Ops...> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef OperationBase<T,Operation<T,OpFunction,Ops...> > OT;
|
||||
typedef OpFunction F;
|
||||
|
||||
static constexpr size_t SIZE = RootSum<Ops...>::SIZE;
|
||||
static constexpr bool FISSTATIC = OpFunction::FISSTATIC;
|
||||
static constexpr bool CONT = false;
|
||||
|
||||
private:
|
||||
std::tuple<Ops...> mOps;
|
||||
std::shared_ptr<OpFunction> mF; // only if non-static
|
||||
|
||||
public:
|
||||
typedef decltype(PackNum<sizeof...(Ops)-1>::template mkSteps<Ops...>(0, mOps)) ETuple;
|
||||
|
||||
Operation(const Ops&... ops);
|
||||
Operation(std::shared_ptr<OpFunction> ff, const Ops&... ops);
|
||||
|
||||
template <class ET>
|
||||
inline auto get(ET pos) const;
|
||||
|
||||
template <class ET>
|
||||
inline Operation& set(ET pos);
|
||||
|
||||
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
||||
-> decltype(PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps));
|
||||
|
||||
template <class Expr>
|
||||
auto loop(Expr exp) const
|
||||
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp));
|
||||
|
||||
T* data() const { assert(0); return nullptr; }
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
template <bool FISSTATIC>
|
||||
struct OpMaker
|
||||
{
|
||||
template <class OpFunction, class... Ops>
|
||||
static inline auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
||||
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
||||
{
|
||||
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(f,ops...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OpMaker<true>
|
||||
{
|
||||
template <class OpFunction, class... Ops>
|
||||
static inline auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
||||
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
||||
{
|
||||
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(ops...);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class OpFunction, class... Ops>
|
||||
auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
||||
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
||||
{
|
||||
return OpMaker<OpFunction::FISSTATIC>::mkOperation(f, ops...);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, class Op, class IndexType>
|
||||
class Contraction : public OperationTemplate<T,Contraction<T,Op,IndexType> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef OperationBase<T,Contraction<T,Op,IndexType> > OT;
|
||||
|
||||
static constexpr size_t SIZE = Op::SIZE;
|
||||
static constexpr bool CONT = Op::CONT;
|
||||
|
||||
private:
|
||||
|
||||
Op mOp;
|
||||
std::shared_ptr<IndexType> mInd;
|
||||
|
||||
public:
|
||||
typedef decltype(mOp.rootSteps(0)) ETuple;
|
||||
|
||||
Contraction(const Op& op, std::shared_ptr<IndexType> ind);
|
||||
|
||||
template <class ET>
|
||||
inline auto get(ET pos) const
|
||||
-> decltype(mOp.template get<ET>(pos));
|
||||
|
||||
template <class ET>
|
||||
inline Contraction& set(ET pos);
|
||||
|
||||
T* data() const { assert(0); return nullptr; }
|
||||
|
||||
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
||||
-> decltype(mOp.rootSteps(iPtrNum));
|
||||
|
||||
template <class Expr>
|
||||
auto loop(Expr exp) const
|
||||
-> decltype(mInd->iforh(1,mOp.loop(exp)));
|
||||
};
|
||||
|
||||
template <typename T, class Op, class... Indices>
|
||||
// class SliceContraction : public OperationTemplate
|
||||
//<MultiArray<T,typename Indices::RangeType...>,
|
||||
//SliceContraction<MultiArray<T,typename Indices::RangeType...>,Op,Indices...> >
|
||||
class SliceContraction : public OperationTemplate<T,SliceContraction<T,Op,Indices...> >
|
||||
{
|
||||
public:
|
||||
typedef MultiArray<T,typename Indices::RangeType...> value_type;
|
||||
typedef OperationTemplate<T,SliceContraction<T,Op,Indices...> > OT;
|
||||
|
||||
static constexpr size_t SIZE = Op::SIZE;
|
||||
static constexpr bool CONT = false;
|
||||
|
||||
private:
|
||||
|
||||
mutable Op mOp;
|
||||
mutable std::shared_ptr<MultiArray<T,typename Indices::RangeType...> > mCont;
|
||||
mutable OperationRoot<T,typename Indices::RangeType...> mTarOp;
|
||||
|
||||
public:
|
||||
typedef decltype(mOp.rootSteps(0)) ETuple;
|
||||
|
||||
SliceContraction(const Op& op, std::shared_ptr<Indices>... ind);
|
||||
|
||||
template <class ET>
|
||||
inline const value_type& get(ET pos) const;
|
||||
|
||||
template <class ET>
|
||||
inline SliceContraction& set(ET pos);
|
||||
|
||||
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
||||
-> decltype(mOp.rootSteps(iPtrNum));
|
||||
|
||||
template <class Expr>
|
||||
auto loop(Expr exp) const -> decltype(mOp.loop(exp)); // no loop
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#include "type_operations.h"
|
||||
|
||||
#endif
|
|
@ -1,109 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/basic_operations.cc.h
|
||||
@brief Basic operations implementation
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_basic_operations_cc_h__
|
||||
#define __cxz_basic_operations_cc_h__
|
||||
|
||||
#include "basic_operations.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/*==================================+
|
||||
| standard operatrions (unary) |
|
||||
+==================================*/
|
||||
|
||||
template <class Op>
|
||||
constexpr decltype(auto) minus(const COpInterface<Op>& op)
|
||||
{
|
||||
return operation( [](const auto& a) { return -a; }, op.THIS() );
|
||||
}
|
||||
|
||||
/*===================================+
|
||||
| standard operatrions (binary) |
|
||||
+===================================*/
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) plus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
|
||||
{
|
||||
return operation( [](const auto& a, const auto& b) { return a + b; },
|
||||
op1.THIS(), op2.THIS() );
|
||||
}
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) minus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
|
||||
{
|
||||
return operation( [](const auto& a, const auto& b) { return a - b; },
|
||||
op1.THIS(), op2.THIS() );
|
||||
}
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) multiplies(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
|
||||
{
|
||||
return operation( [](const auto& a, const auto& b) { return a * b; },
|
||||
op1.THIS(), op2.THIS() );
|
||||
}
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) divides(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
|
||||
{
|
||||
return operation( [](const auto& a, const auto& b) { return a / b; },
|
||||
op1.THIS(), op2.THIS() );
|
||||
}
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) modulo(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
|
||||
{
|
||||
return operation( [](const auto& a, const auto& b) { return a % b; },
|
||||
op1.THIS(), op2.THIS() );
|
||||
}
|
||||
|
||||
/*=======================================+
|
||||
| operators for standard operations |
|
||||
+=======================================*/
|
||||
|
||||
template <class Op>
|
||||
constexpr decltype(auto) operator-(const COpInterface<Op>& op)
|
||||
{
|
||||
return minus(op);
|
||||
}
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) operator+(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
|
||||
{
|
||||
return plus(op1, op2);
|
||||
}
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) operator-(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
|
||||
{
|
||||
return minus(op1, op2);
|
||||
}
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) operator*(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
|
||||
{
|
||||
return multiplies(op1, op2);
|
||||
}
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) operator/(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
|
||||
{
|
||||
return divides(op1, op2);
|
||||
}
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) operator%(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
|
||||
{
|
||||
return modulo(op1, op2);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,65 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/basic_operations.h
|
||||
@brief Basic operations declaration
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_basic_operations_h__
|
||||
#define __cxz_basic_operations_h__
|
||||
|
||||
#include "base/base.h"
|
||||
#include "operation.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
// standard operations:
|
||||
// unary:
|
||||
|
||||
template <class Op>
|
||||
constexpr decltype(auto) minus(const COpInterface<Op>& op);
|
||||
|
||||
// binary:
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) plus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) minus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) multiplies(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) divides(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) modulo(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
|
||||
|
||||
// operators for standard operations:
|
||||
|
||||
template <class Op>
|
||||
constexpr decltype(auto) operator-(const COpInterface<Op>& op);
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) operator+(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) operator-(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) operator*(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) operator/(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
|
||||
|
||||
template <class Op1, class Op2>
|
||||
constexpr decltype(auto) operator%(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,279 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/extensions/avx.cc.h
|
||||
@brief Register type implementaions for AVX.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_avx_cc_h__
|
||||
#define __cxz_avx_cc_h__
|
||||
|
||||
#include "avx.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/*=====================+
|
||||
| PlusCC / PlusCX |
|
||||
+=====================*/
|
||||
|
||||
inline decltype(auto)
|
||||
PlusCC<Double,Double,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_add_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
inline decltype(auto)
|
||||
PlusCC<Double,Double,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_add_pd(av, bv);
|
||||
_mm256_store_pd(a.mD, ov);
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
PlusCX<Double,X,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
|
||||
const X& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
|
||||
__m256d ov = _mm256_add_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
PlusCX<Double,X,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a, const X& b)
|
||||
{
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
|
||||
__m256d ov = _mm256_add_pd(av, bv);
|
||||
_mm256_store_pd(a.mD, ov);
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
PlusCX<Double,X,AVX::ND>::eval(const X& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_set1_pd( static_cast<Double>(a) );
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_add_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
/*=======================+
|
||||
| MinusCC / MinusCX |
|
||||
+=======================*/
|
||||
|
||||
inline decltype(auto)
|
||||
MinusCC<Double,Double,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_sub_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
inline decltype(auto)
|
||||
MinusCC<Double,Double,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_sub_pd(av, bv);
|
||||
_mm256_store_pd(a.mD, ov);
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
MinusCX<Double,X,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
|
||||
const X& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
|
||||
__m256d ov = _mm256_sub_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
MinusCX<Double,X,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a, const X& b)
|
||||
{
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
|
||||
__m256d ov = _mm256_sub_pd(av, bv);
|
||||
_mm256_store_pd(a.mD, ov);
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
MinusCX<Double,X,AVX::ND>::eval(const X& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_set1_pd( static_cast<Double>(a) );
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_sub_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
/*=================================+
|
||||
| MultipliesCC / MultipliesCX |
|
||||
+=================================*/
|
||||
|
||||
inline decltype(auto)
|
||||
MultipliesCC<Double,Double,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_mul_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
inline decltype(auto)
|
||||
MultipliesCC<Double,Double,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_mul_pd(av, bv);
|
||||
_mm256_store_pd(a.mD, ov);
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
MultipliesCX<Double,X,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
|
||||
const X& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
|
||||
__m256d ov = _mm256_mul_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
MultipliesCX<Double,X,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a,
|
||||
const X& b)
|
||||
{
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
|
||||
__m256d ov = _mm256_mul_pd(av, bv);
|
||||
_mm256_store_pd(a.mD, ov);
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
MultipliesCX<Double,X,AVX::ND>::eval(const X& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_set1_pd( static_cast<Double>(a) );
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_mul_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/*===========================+
|
||||
| DividesCC / DividesCX |
|
||||
+===========================*/
|
||||
|
||||
inline decltype(auto)
|
||||
DividesCC<Double,Double,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_div_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
inline decltype(auto)
|
||||
DividesCC<Double,Double,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_div_pd(av, bv);
|
||||
_mm256_store_pd(a.mD, ov);
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
DividesCX<Double,X,AVX::ND>::eval(const Consecutive<Double,AVX::ND>& a,
|
||||
const X& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
|
||||
__m256d ov = _mm256_div_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
DividesCX<Double,X,AVX::ND>::aeval(Consecutive<Double,AVX::ND>& a, const X& b)
|
||||
{
|
||||
__m256d av = _mm256_load_pd(a.mD);
|
||||
__m256d bv = _mm256_set1_pd( static_cast<Double>(b) );
|
||||
__m256d ov = _mm256_div_pd(av, bv);
|
||||
_mm256_store_pd(a.mD, ov);
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
inline decltype(auto)
|
||||
DividesCX<Double,X,AVX::ND>::eval(const X& a,
|
||||
const Consecutive<Double,AVX::ND>& b)
|
||||
{
|
||||
Consecutive<Double,AVX::ND> o;
|
||||
__m256d av = _mm256_set1_pd( static_cast<Double>(a) );
|
||||
__m256d bv = _mm256_load_pd(b.mD);
|
||||
__m256d ov = _mm256_div_pd(av, bv);
|
||||
_mm256_store_pd(o.mD, ov);
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,120 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/extensions/avx.h
|
||||
@brief Register type specialization for AVX.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_avx_h__
|
||||
#define __cxz_avx_h__
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
#include "base/base.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
namespace AVX
|
||||
{
|
||||
static constexpr SizeT ND = AVX_VSIZE/sizeof(Double);
|
||||
static constexpr SizeT NF = AVX_VSIZE/sizeof(float);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct PlusCC<Double,Double,AVX::ND>
|
||||
{
|
||||
static inline decltype(auto)
|
||||
eval(const Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
aeval(Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
|
||||
};
|
||||
|
||||
template <typename X>
|
||||
struct PlusCX<Double,X,AVX::ND>
|
||||
{
|
||||
static inline decltype(auto)
|
||||
eval(const Consecutive<Double,AVX::ND>& a, const X& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
aeval(Consecutive<Double,AVX::ND>& a, const X& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
eval(const X& a, const Consecutive<Double,AVX::ND>& b);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct MinusCC<Double,Double,AVX::ND>
|
||||
{
|
||||
static inline decltype(auto)
|
||||
eval(const Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
aeval(Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
|
||||
};
|
||||
|
||||
template <typename X>
|
||||
struct MinusCX<Double,X,AVX::ND>
|
||||
{
|
||||
static inline decltype(auto)
|
||||
eval(const Consecutive<Double,AVX::ND>& a, const X& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
aeval(Consecutive<Double,AVX::ND>& a, const X& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
eval(const X& a, const Consecutive<Double,AVX::ND>& b);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct MultipliesCC<Double,Double,AVX::ND>
|
||||
{
|
||||
static inline decltype(auto)
|
||||
eval(const Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
aeval(Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
|
||||
};
|
||||
|
||||
template <typename X>
|
||||
struct MultipliesCX<Double,X,AVX::ND>
|
||||
{
|
||||
static inline decltype(auto)
|
||||
eval(const Consecutive<Double,AVX::ND>& a, const X& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
aeval(Consecutive<Double,AVX::ND>& a, const X& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
eval(const X& a, const Consecutive<Double,AVX::ND>& b);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DividesCC<Double,Double,AVX::ND>
|
||||
{
|
||||
static inline decltype(auto)
|
||||
eval(const Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
aeval(Consecutive<Double,AVX::ND>& a, const Consecutive<Double,AVX::ND>& b);
|
||||
};
|
||||
|
||||
template <typename X>
|
||||
struct DividesCX<Double,X,AVX::ND>
|
||||
{
|
||||
static inline decltype(auto)
|
||||
eval(const Consecutive<Double,AVX::ND>& a, const X& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
aeval(Consecutive<Double,AVX::ND>& a, const X& b);
|
||||
|
||||
static inline decltype(auto)
|
||||
eval(const X& a, const Consecutive<Double,AVX::ND>& b);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,21 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/extensions/extensions.cc.h
|
||||
@brief Operation extensions template implementations main header.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_extensions_cc_h__
|
||||
#define __cxz_extensions_cc_h__
|
||||
|
||||
#include "reg.cc.h"
|
||||
|
||||
#if CXZ_HAVE_AVX
|
||||
#include "avx.cc.h"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,23 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/extensions/extensions.h
|
||||
@brief Operation extensions main header.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_extensions_h__
|
||||
#define __cxz_extensions_h__
|
||||
|
||||
#include "reg.h"
|
||||
|
||||
#if CXZ_HAVE_AVX
|
||||
#include "avx.h"
|
||||
#endif
|
||||
|
||||
#include "extensions.cc.h"
|
||||
|
||||
#endif
|
|
@ -1,262 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/extensions/reg.cc.h
|
||||
@brief Register type template implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_reg_cc_h__
|
||||
#define __cxz_reg_cc_h__
|
||||
|
||||
#include "reg.h"
|
||||
#include "xpr/pos_type.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
template <typename T, class EPosT, SizeT... Is>
|
||||
inline decltype(auto) vregi(const T* d, const EPosT& pos, std::index_sequence<Is...> is)
|
||||
{
|
||||
constexpr SizeT N = epos_size<EPosT>::value;
|
||||
static_assert(N == sizeof...(Is), "got inconsistent index sequence");
|
||||
return Consecutive<T,N> { d[pos.template get<Is>().val()]... };
|
||||
}
|
||||
|
||||
template <typename T, class EPosT>
|
||||
inline decltype(auto) vreg(const T* d, const EPosT& pos)
|
||||
{
|
||||
constexpr SizeT N = epos_size<EPosT>::value;
|
||||
static_assert(is_epos_type<EPosT>::value, "got non-epos-type");
|
||||
if constexpr(pos_type_is_consecutive<EPosT>::value){
|
||||
return *reinterpret_cast<const Consecutive<T,N>*>(d+pos.scal().val());
|
||||
}
|
||||
else {
|
||||
return vregi(d, pos, std::make_index_sequence<N>{});
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, class EPosT>
|
||||
inline decltype(auto) vreg(T* d, const EPosT& pos)
|
||||
{
|
||||
constexpr SizeT N = epos_size<EPosT>::value;
|
||||
static_assert(is_epos_type<EPosT>::value, "got non-epos-type");
|
||||
static_assert(pos_type_is_consecutive<EPosT>::value, "no write access for non-consecutive");
|
||||
if constexpr(pos_type_is_consecutive<EPosT>::value){
|
||||
return *reinterpret_cast<Consecutive<T,N>*>(d+pos.scal().val());
|
||||
}
|
||||
else {
|
||||
return vregi(d, pos, std::make_index_sequence<N>{});
|
||||
}
|
||||
}
|
||||
|
||||
template <SizeT I, typename T>
|
||||
constexpr decltype(auto) consecGet(const T& a)
|
||||
{
|
||||
if constexpr(is_consecutive_type<T>::value){
|
||||
static_assert(I < consecutive_size<T>::value,
|
||||
"consecutive index out of range");
|
||||
return a.mD[I];
|
||||
}
|
||||
else {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
template <SizeT I, typename T>
|
||||
constexpr decltype(auto) consecGet(T& a)
|
||||
{
|
||||
if constexpr(is_consecutive_type<T>::value){
|
||||
static_assert(I < consecutive_size<T>::value,
|
||||
"consecutive index out of range");
|
||||
return a.mD[I];
|
||||
}
|
||||
else {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
template <SizeT I, class F, typename... Args>
|
||||
constexpr decltype(auto) consecApply(const F& f, const Args&... args)
|
||||
{
|
||||
return f( consecGet<I>(args)... );
|
||||
}
|
||||
|
||||
template <SizeT I, class F, typename Dst, typename... Args>
|
||||
constexpr Dst& consecAssign(const F& f, Dst& dst, const Args&... args)
|
||||
{
|
||||
f( consecGet<I>(dst), consecGet<I>(args)... );
|
||||
return dst;
|
||||
}
|
||||
|
||||
template <class F, typename... Args, SizeT... Is>
|
||||
constexpr decltype(auto) consecFuncI(const F& f, const Args&... args,
|
||||
std::index_sequence<Is...> is)
|
||||
{
|
||||
typedef decltype(consecApply<0>(f, args...)) OType;
|
||||
constexpr SizeT N = sizeof...(Is);
|
||||
return Consecutive<OType,N> { consecApply<Is>(f, args...) ... };
|
||||
}
|
||||
|
||||
template <class F, typename Dst, typename... Args, SizeT... Is>
|
||||
constexpr Dst& consecFuncAI(const F& f, Dst& dst, const Args&... args,
|
||||
std::index_sequence<Is...> is)
|
||||
{
|
||||
( consecAssign<Is>(f, dst, args...), ... );
|
||||
return dst;
|
||||
}
|
||||
|
||||
template <SizeT N, class F, typename... Args>
|
||||
constexpr decltype(auto) consecFunc(const F& f, const Args&... args)
|
||||
{
|
||||
return consecFuncI<F,Args...>(f, args..., std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
template <SizeT N, class F, typename Dst, typename... Args>
|
||||
constexpr Dst& consecFuncA(const F& f, Dst& dst, const Args&... args)
|
||||
{
|
||||
return consecFuncAI<F,Dst,Args...>(f, dst, args..., std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
/*============================+
|
||||
| basic operations: plus |
|
||||
+============================*/
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto)
|
||||
PlusCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x + y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto)
|
||||
PlusCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||
{
|
||||
return consecFuncA<N>( [](auto& x, const auto& y) { return x += y; }, o, a );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) PlusCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x + y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) PlusCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x + y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) PlusCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
|
||||
{
|
||||
return consecFuncA<N>( [](auto& x, const auto& y) { return x += y; }, o, a );
|
||||
}
|
||||
|
||||
/*=============================+
|
||||
| basic operations: minus |
|
||||
+=============================*/
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) MinusCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x - y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) MinusCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x - y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) MinusCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x - y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) MinusCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||
{
|
||||
return consecFuncA<N>( [](auto& x, const auto& y) { return x -= y; }, o, a );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) MinusCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
|
||||
{
|
||||
return consecFuncA<N>( [](auto& x, const auto& y) { return x -= y; }, o, a );
|
||||
}
|
||||
|
||||
/*=================================+
|
||||
| basic operations: muliplies |
|
||||
+=================================*/
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) MultipliesCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x * y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) MultipliesCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x * y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) MultipliesCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x * y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) MultipliesCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||
{
|
||||
return consecFuncA<N>( [](const auto& x, const auto& y) { return x *= y; }, o, a );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) MultipliesCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
|
||||
{
|
||||
return consecFuncA<N>( [](const auto& x, const auto& y) { return x *= y; }, o, a );
|
||||
}
|
||||
|
||||
/*===============================+
|
||||
| basic operations: divides |
|
||||
+===============================*/
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) DividesCC<T,U,N>::eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x / y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) DividesCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x / y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) DividesCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
|
||||
{
|
||||
return consecFunc<N>( [](const auto& x, const auto& y) { return x / y; }, a, b );
|
||||
}
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) DividesCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||
{
|
||||
return consecFuncA<N>( [](const auto& x, const auto& y) { return x /= y; }, o, a );
|
||||
}
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
constexpr decltype(auto) DividesCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
|
||||
{
|
||||
return consecFuncA<N>( [](const auto& x, const auto& y) { return x /= y; }, o, a );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,279 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/extensions/reg.h
|
||||
@brief Register type declaration.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_reg_h__
|
||||
#define __cxz_reg_h__
|
||||
|
||||
#include "base/base.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
// no use of Arr = std::array here, since I want ensure that
|
||||
// it has exactly a memory size of N
|
||||
template <typename T, SizeT N>
|
||||
struct Consecutive
|
||||
{
|
||||
T mD[N];
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_consecutive_type { CXZ_CVAL_FALSE; };
|
||||
|
||||
template <typename T>
|
||||
struct consecutive_base { typedef T type; };
|
||||
|
||||
template <typename T>
|
||||
struct consecutive_size { static constexpr SizeT value = 0; };
|
||||
|
||||
template <typename T, SizeT N>
|
||||
struct is_consecutive_type<Consecutive<T,N>> { CXZ_CVAL_TRUE; };
|
||||
|
||||
template <typename T, SizeT N>
|
||||
struct consecutive_base<Consecutive<T,N>> { typedef T type; };
|
||||
|
||||
template <typename T, SizeT N>
|
||||
struct consecutive_size<Consecutive<T,N>> { static constexpr SizeT value = N; };
|
||||
|
||||
/*======================================+
|
||||
| consecutive generating functions |
|
||||
+======================================*/
|
||||
|
||||
template <typename T, class EPosT, SizeT... Is>
|
||||
inline decltype(auto) vregi(const T* d, const EPosT& pos, std::index_sequence<Is...> is);
|
||||
|
||||
template <typename T, class EPosT>
|
||||
inline decltype(auto) vreg(const T* d, const EPosT& pos);
|
||||
|
||||
template <typename T, class EPosT>
|
||||
inline decltype(auto) vreg(T* d, const EPosT& pos);
|
||||
|
||||
/*================+
|
||||
| ConsecFunc |
|
||||
+================*/
|
||||
|
||||
template <SizeT I, typename T>
|
||||
constexpr decltype(auto) consecGet(const T& a);
|
||||
|
||||
template <SizeT I, typename T>
|
||||
constexpr decltype(auto) consecGet(T& a);
|
||||
|
||||
template <SizeT I, class F, typename... Args>
|
||||
constexpr decltype(auto) consecApply(const F& f, const Args&... args);
|
||||
|
||||
template <SizeT I, class F, typename Dst, typename... Args>
|
||||
constexpr Dst& consecAssign(const F& f, Dst& dst, const Args&... args);
|
||||
|
||||
template <class F, typename... Args, SizeT... Is>
|
||||
constexpr decltype(auto) consecFuncI(const F& f, const Args&... args,
|
||||
std::index_sequence<Is...> is);
|
||||
|
||||
template <class F, typename Dst, typename... Args, SizeT... Is>
|
||||
constexpr Dst& consecFuncAI(const F& f, Dst& dst, const Args&... args,
|
||||
std::index_sequence<Is...> is);
|
||||
|
||||
template <SizeT N, class F, typename... Args>
|
||||
constexpr decltype(auto) consecFunc(const F& f, const Args&... args);
|
||||
|
||||
template <SizeT N, class F, typename Dst, typename... Args>
|
||||
constexpr Dst& consecFuncA(const F& f, Dst& dst, const Args&... args);
|
||||
|
||||
/*============================+
|
||||
| basic operations: plus |
|
||||
+============================*/
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
struct PlusCC
|
||||
{
|
||||
static constexpr decltype(auto)
|
||||
eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
aeval(Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||
};
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
struct PlusCX
|
||||
{
|
||||
static constexpr decltype(auto)
|
||||
eval(const Consecutive<T,N>& a, const X& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
aeval(Consecutive<T,N>& a, const X& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
eval(const X& a, const Consecutive<T,N>& b);
|
||||
};
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator+(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||
{ return PlusCC<T,U,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator+(const Consecutive<T,N>& a, const U& b)
|
||||
{ return PlusCX<T,U,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator+(const T& a, const Consecutive<U,N>& b)
|
||||
{ return PlusCX<U,T,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr Consecutive<T,N>& operator+=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||
{ return PlusCC<T,U,N>::aeval(o,a); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr Consecutive<T,N>& operator+=(Consecutive<T,N>& o, const U& a)
|
||||
{ return PlusCX<T,U,N>::aeval(o,a); }
|
||||
|
||||
/*=============================+
|
||||
| basic operations: minus |
|
||||
+=============================*/
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
struct MinusCC
|
||||
{
|
||||
static constexpr decltype(auto)
|
||||
eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
aeval(Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||
};
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
struct MinusCX
|
||||
{
|
||||
static constexpr decltype(auto)
|
||||
eval(const Consecutive<T,N>& a, const X& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
aeval(Consecutive<T,N>& a, const X& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
eval(const X& a, const Consecutive<T,N>& b);
|
||||
};
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator-(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||
{ return MinusCC<T,U,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator-(const Consecutive<T,N>& a, const U& b)
|
||||
{ return MinusCX<T,U,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator-(const T& a, const Consecutive<U,N>& b)
|
||||
{ return MinusCX<U,T,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr Consecutive<T,N>& operator-=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||
{ return MinusCC<T,U,N>::eval(o,a); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr Consecutive<T,N>& operator-=(Consecutive<T,N>& o, const U& a)
|
||||
{ return MinusCX<T,U,N>::eval(o,a); }
|
||||
|
||||
/*=================================+
|
||||
| basic operations: muliplies |
|
||||
+=================================*/
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
struct MultipliesCC
|
||||
{
|
||||
static constexpr decltype(auto)
|
||||
eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
aeval(Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||
};
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
struct MultipliesCX
|
||||
{
|
||||
static constexpr decltype(auto)
|
||||
eval(const Consecutive<T,N>& a, const X& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
aeval(Consecutive<T,N>& a, const X& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
eval(const X& a, const Consecutive<T,N>& b);
|
||||
};
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator*(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||
{ return MultipliesCC<T,U,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator*(const Consecutive<T,N>& a, const U& b)
|
||||
{ return MultipliesCX<T,U,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator*(const T& a, const Consecutive<U,N>& b)
|
||||
{ return MultipliesCX<U,T,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr Consecutive<T,N>& operator*=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||
{ return MultipliesCC<T,U,N>::eval(o,a); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr Consecutive<T,N>& operator*=(Consecutive<T,N>& o, const U& a)
|
||||
{ return MultipliesCX<T,U,N>::eval(o,a); }
|
||||
|
||||
/*===============================+
|
||||
| basic operations: divides |
|
||||
+===============================*/
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
struct DividesCC
|
||||
{
|
||||
static constexpr decltype(auto)
|
||||
eval(const Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
aeval(Consecutive<T,N>& a, const Consecutive<U,N>& b);
|
||||
};
|
||||
|
||||
template <typename T, typename X, SizeT N>
|
||||
struct DividesCX
|
||||
{
|
||||
static constexpr decltype(auto)
|
||||
eval(const Consecutive<T,N>& a, const X& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
aeval(Consecutive<T,N>& a, const X& b);
|
||||
|
||||
static constexpr decltype(auto)
|
||||
eval(const X& a, const Consecutive<T,N>& b);
|
||||
};
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator/(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
|
||||
{ return DividesCC<T,U,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator/(const Consecutive<T,N>& a, const U& b)
|
||||
{ return DividesCX<T,U,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr decltype(auto) operator/(const T& a, const Consecutive<U,N>& b)
|
||||
{ return DividesCX<U,T,N>::eval(a,b); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr Consecutive<T,N>& operator/=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
|
||||
{ return DividesCC<T,U,N>::eval(o,a); }
|
||||
|
||||
template <typename T, typename U, SizeT N>
|
||||
constexpr Consecutive<T,N>& operator/=(Consecutive<T,N>& o, const U& a)
|
||||
{ return DividesCX<T,U,N>::eval(o,a); }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,515 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/op_types.cc.h
|
||||
@brief Operation types template implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_op_types_cc_h__
|
||||
#define __cxz_op_types_cc_h__
|
||||
|
||||
#include "op_types.h"
|
||||
#include "op_utility.h"
|
||||
#include "extensions/extensions.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
/*====================+
|
||||
| COpInterface |
|
||||
+====================*/
|
||||
|
||||
template <class OpT>
|
||||
template <class F, class IndexT>
|
||||
constexpr decltype(auto) COpInterface<OpT>::c(F&& f, const Sptr<IndexT>& ind) const
|
||||
{
|
||||
return contraction(std::forward<F>(f), THIS().r(), ind);
|
||||
}
|
||||
|
||||
template <class OpT>
|
||||
template <class IndexT>
|
||||
constexpr decltype(auto) COpInterface<OpT>::c(const Sptr<IndexT>& ind) const
|
||||
{
|
||||
return contraction([](auto& a, const auto& b) { a += b; },
|
||||
THIS(), ind);
|
||||
}
|
||||
|
||||
template <class OpT>
|
||||
template <class F, class... Args>
|
||||
constexpr decltype(auto) COpInterface<OpT>::o(F&& f, Args&&... args) const
|
||||
{
|
||||
return operation(std::forward<F>(f), THIS().r(), args...);
|
||||
}
|
||||
|
||||
|
||||
/*===================+
|
||||
| OpInterface |
|
||||
+===================*/
|
||||
|
||||
template <class OpT>
|
||||
template <class IndexT, class F, class... Args>
|
||||
constexpr decltype(auto) OpInterface<OpT>::ax(const Sptr<IndexT>& ind, F&& f, const Args&... args)
|
||||
{
|
||||
return ind->ifor( operation(f, OI::THIS().r(), args...), NoF {} );
|
||||
}
|
||||
|
||||
template <class OpT>
|
||||
template <class IndexT, class F, class... Args>
|
||||
inline void OpInterface<OpT>::a(const Sptr<IndexT>& ind, F&& f, const Args&... args)
|
||||
{
|
||||
ax(ind, f, args...)();
|
||||
}
|
||||
|
||||
|
||||
/*=============+
|
||||
| COpRoot |
|
||||
+=============*/
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr COpRoot<T,IndexT>::COpRoot(const CArrayBase<T>& a, const Sptr<IndexT>& ind) :
|
||||
mData(a.data()+ind->pos()),
|
||||
mIndex(ind)
|
||||
{}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr COpRoot<T,IndexT>::COpRoot(const T* data, const Sptr<IndexT>& ind) :
|
||||
mData(data+ind->pos()),
|
||||
mIndex(ind)
|
||||
{}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr COpRoot<T,IndexT>& COpRoot<T,IndexT>::init(const T* data, const Sptr<IndexT>& ind)
|
||||
{
|
||||
mData = data+ind->pos();
|
||||
mIndex = ind;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
template <class PosT>
|
||||
constexpr decltype(auto) COpRoot<T,IndexT>::operator()(const PosT& pos) const
|
||||
{
|
||||
if constexpr(is_epos_type<PosT>::value){
|
||||
return vreg(mData,pos); // distinguish between consecutive/non-consecutive
|
||||
}
|
||||
else {
|
||||
return mData[pos.val()];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr decltype(auto) COpRoot<T,IndexT>::operator()() const
|
||||
{
|
||||
return mData[0];
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
template <SizeT I>
|
||||
constexpr decltype(auto) COpRoot<T,IndexT>::rootSteps(const IndexId<I>& id) const
|
||||
{
|
||||
return mIndex->stepSize(id);
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
const T* COpRoot<T,IndexT>::data() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr decltype(auto) coproot(const CArrayBase<T>& a, const Sptr<IndexT>& ind)
|
||||
{
|
||||
return COpRoot<T,IndexT>(a, ind);
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr decltype(auto) coproot(const T* a, const Sptr<IndexT>& ind)
|
||||
{
|
||||
return COpRoot<T,IndexT>(a, ind);
|
||||
}
|
||||
|
||||
/*=============+
|
||||
| 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) :
|
||||
mIndex(ind),
|
||||
mC(std::make_shared<Vector<T>>(mIndex->pmax().val()))
|
||||
{}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::init(const Sptr<IndexT>& ind)
|
||||
{
|
||||
mIndex = ind;
|
||||
if(mC.size() != mIndex->pmax().val()){
|
||||
mC.resize(mIndex->pmax().val());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::init(const Sptr<IndexT>& ind,
|
||||
const Vector<T>& c)
|
||||
{
|
||||
init(ind);
|
||||
CXZ_ASSERT(c.size() == mC.size(),
|
||||
"size-mismatch: expected " << mC.size() << ", got " << c.size());
|
||||
std::transform(c.begin(), c.end(), mC.begin(), [](const auto& x) { return x; } );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr decltype(auto) OpCont<T,IndexT>::r()
|
||||
{
|
||||
return OpRoot<T,IndexT>(data(), mIndex);
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr decltype(auto) OpCont<T,IndexT>::r() const
|
||||
{
|
||||
return COpRoot<T,IndexT>(data(), mIndex);
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
template <class Op>
|
||||
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator=(const Op& o)
|
||||
{
|
||||
// TODO: build and execute assign expression forwarding outer index
|
||||
// if a1 and a2 are non-expression types (like it is the case now),
|
||||
// just do what is currently implemented
|
||||
OI::a(mIndex, [](auto& a1, const auto& a2) { a1 = a2; }, o);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
template <class Op>
|
||||
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator+=(const Op& o)
|
||||
{
|
||||
OI::a(mIndex, [](auto& a1, const auto& a2) { a1 += a2; }, o);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator=(const OpCont<T,IndexT>& o)
|
||||
{
|
||||
OI::a(mIndex, [](auto& a1, const auto& a2) { a1 = a2; }, o);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
template <class PosT>
|
||||
constexpr decltype(auto) OpCont<T,IndexT>::operator()(const PosT& pos) const
|
||||
{
|
||||
if constexpr(is_epos_type<PosT>::value){
|
||||
if constexpr(pos_type_is_consecutive<PosT>::value){
|
||||
return vreg(mC.data(),pos);
|
||||
}
|
||||
else {
|
||||
// non-consecutive data cannot be directly accessed
|
||||
// so there is no non-const (write) access!
|
||||
return vreg(const_cast<const T*>(mC.data()),pos);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return mC[pos.val()];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr decltype(auto) OpCont<T,IndexT>::operator()() const
|
||||
{
|
||||
return mC[0];
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
template <SizeT I>
|
||||
constexpr decltype(auto) OpCont<T,IndexT>::rootSteps(const IndexId<I>& id) const
|
||||
{
|
||||
return mIndex->stepSize(id);
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
T* OpCont<T,IndexT>::data()
|
||||
{
|
||||
return mC.data();
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
const T* OpCont<T,IndexT>::data() const
|
||||
{
|
||||
return mC.data();
|
||||
}
|
||||
|
||||
/*==============+
|
||||
| OpRoot |
|
||||
+==============*/
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr OpRoot<T,IndexT>::OpRoot(ArrayBase<T>& a, const Sptr<IndexT>& ind) :
|
||||
mData(a.data()+ind->pos()),
|
||||
mIndex(ind)
|
||||
{}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr OpRoot<T,IndexT>::OpRoot(T* data, const Sptr<IndexT>& ind) :
|
||||
mData(data+ind->pos()),
|
||||
mIndex(ind)
|
||||
{}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::init(T* data, const Sptr<IndexT>& ind)
|
||||
{
|
||||
mData = data+ind->pos();
|
||||
mIndex = ind;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
template <class Op>
|
||||
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::operator=(const Op& o)
|
||||
{
|
||||
OI::a(mIndex, [](auto& a, const auto& b) { a = b; }, o);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
template <class Op>
|
||||
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::operator+=(const Op& o)
|
||||
{
|
||||
OI::a(mIndex, [](auto& a, const auto& b) { a += b; }, o);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::operator=(const OpRoot<T,IndexT>& o)
|
||||
{
|
||||
OI::a(mIndex, [](auto& a, const auto& b) { a = b; }, o);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
template <class PosT>
|
||||
constexpr decltype(auto) OpRoot<T,IndexT>::operator()(const PosT& pos) const
|
||||
{
|
||||
if constexpr(is_epos_type<PosT>::value){
|
||||
if constexpr(pos_type_is_consecutive<PosT>::value){
|
||||
return vreg(mData,pos);
|
||||
}
|
||||
else {
|
||||
// non-consecutive data cannot be directly accessed
|
||||
// so there is no non-const (write) access!
|
||||
return vreg(const_cast<const T*>(mData),pos);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return mData[pos.val()];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr decltype(auto) OpRoot<T,IndexT>::operator()() const
|
||||
{
|
||||
return mData[0];
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
template <SizeT I>
|
||||
constexpr decltype(auto) OpRoot<T,IndexT>::rootSteps(const IndexId<I>& id) const
|
||||
{
|
||||
return mIndex->stepSize(id);
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
T* OpRoot<T,IndexT>::data() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr decltype(auto) oproot(ArrayBase<T>& a, const Sptr<IndexT>& ind)
|
||||
{
|
||||
return OpRoot<T,IndexT>(a, ind);
|
||||
}
|
||||
|
||||
/*=================+
|
||||
| Operation |
|
||||
+=================*/
|
||||
|
||||
template <class F, class... Ops>
|
||||
constexpr Operation<F,Ops...>::Operation(F&& f, const Ops&... ops) :
|
||||
mOps(ops...),
|
||||
mF(std::forward<F>(f))
|
||||
{}
|
||||
|
||||
template <class F, class... Ops>
|
||||
template <class PosT>
|
||||
constexpr decltype(auto) Operation<F,Ops...>::operator()(const PosT& pos) const
|
||||
{
|
||||
return pos_unpack_args(mF, pos, mOps);
|
||||
}
|
||||
|
||||
template <class F, class... Ops>
|
||||
constexpr decltype(auto) Operation<F,Ops...>::operator()() const
|
||||
{
|
||||
return exec(std::make_index_sequence<sizeof...(Ops)>{});
|
||||
}
|
||||
|
||||
template <class F, class... Ops>
|
||||
template <SizeT I>
|
||||
constexpr decltype(auto) Operation<F,Ops...>::rootSteps(const IndexId<I>& id) const
|
||||
{
|
||||
return rootStepsi(id, std::make_index_sequence<sizeof...(Ops)>{});
|
||||
}
|
||||
|
||||
template <class F, class... Ops>
|
||||
template <SizeT... Is>
|
||||
constexpr decltype(auto) Operation<F,Ops...>::exec(std::index_sequence<Is...> is) const
|
||||
{
|
||||
return mF( std::get<Is>(mOps)() ... );
|
||||
}
|
||||
|
||||
template <class F, class... Ops>
|
||||
template <SizeT I, SizeT... Is>
|
||||
constexpr decltype(auto) Operation<F,Ops...>::rootStepsi(const IndexId<I>& id,
|
||||
std::index_sequence<Is...> is) const
|
||||
{
|
||||
return ( std::get<Is>(mOps).rootSteps(id) << ... );
|
||||
}
|
||||
|
||||
template <class F, class... Ops>
|
||||
constexpr decltype(auto) operation(F&& f, const Ops&... ops)
|
||||
{
|
||||
return Operation<F,Ops...>(std::forward<F>(f), ops...);
|
||||
}
|
||||
|
||||
template <class Tar, class Src>
|
||||
constexpr decltype(auto) assignxpr(const Tar& tar, const Src& src)
|
||||
{
|
||||
static_assert(is_xpr<Tar>::value, "expected expression");
|
||||
if constexpr(is_xpr<Src>::value){
|
||||
return operation([](auto& a, const auto& b) { a = b; }, tar, src);
|
||||
}
|
||||
else {
|
||||
return operation([&](auto& a) { a = src; }, tar);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tar, class Src>
|
||||
constexpr decltype(auto) assignxpr(Tar& tar, const Src& src)
|
||||
{
|
||||
if constexpr(is_xpr<Tar>::value){
|
||||
if constexpr(is_xpr<Src>::value){
|
||||
return operation([](auto& a, const auto& b) { a = b; }, tar, src);
|
||||
}
|
||||
else {
|
||||
return operation([&](auto& a) { a = src; }, tar);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr(is_xpr<Src>::value){
|
||||
return operation([&](const auto& b) { tar = b; }, src);
|
||||
}
|
||||
else {
|
||||
return operation([&]() { tar = src; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*===================+
|
||||
| Contraction |
|
||||
+===================*/
|
||||
|
||||
template <class CXpr>
|
||||
constexpr Contraction<CXpr>::Contraction(CXpr&& cxpr) :
|
||||
mCXpr(cxpr)
|
||||
{}
|
||||
|
||||
template <class CXpr>
|
||||
template <class PosT>
|
||||
constexpr decltype(auto) Contraction<CXpr>::operator()(const PosT& pos) const
|
||||
{
|
||||
return mCXpr(pos);
|
||||
}
|
||||
|
||||
template <class CXpr>
|
||||
constexpr decltype(auto) Contraction<CXpr>::operator()() const
|
||||
{
|
||||
return mCXpr();
|
||||
}
|
||||
|
||||
template <class CXpr>
|
||||
template <SizeT I>
|
||||
constexpr decltype(auto) Contraction<CXpr>::rootSteps(const IndexId<I>& id) const
|
||||
{
|
||||
return mCXpr.rootSteps(id);
|
||||
}
|
||||
|
||||
template <class F, class Op, class IndexT>
|
||||
constexpr decltype(auto) contraction(F&& f, Op&& op, const Sptr<IndexT>& i)
|
||||
{
|
||||
typedef decltype(i->ifor( op, f )) CXprT; // TODO: implement ifor with func arg!!!
|
||||
return Contraction<CXprT>( i->ifor( op, f ) );
|
||||
}
|
||||
|
||||
/*======================+
|
||||
| various functions |
|
||||
+======================*/
|
||||
|
||||
template <class IndexT>
|
||||
constexpr decltype(auto) indexOp(const Sptr<IndexT>& i)
|
||||
{
|
||||
return i->xpr(i);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,298 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/op_types.h
|
||||
@brief Operation types declarations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_op_types_h__
|
||||
#define __cxz_op_types_h__
|
||||
|
||||
#include "base/base.h"
|
||||
#include "xpr/xpr_base.h"
|
||||
#include "array/array_base.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
|
||||
|
||||
template <class OpT>
|
||||
class COpInterface : public XprInterface<OpT>
|
||||
{
|
||||
public:
|
||||
constexpr COpInterface() = default;
|
||||
|
||||
OpT& THIS() { return static_cast<OpT&>(*this); }
|
||||
const OpT& THIS() const { return static_cast<const OpT&>(*this); }
|
||||
|
||||
constexpr decltype(auto) r() { return THIS(); }
|
||||
constexpr decltype(auto) r() const { return THIS(); }
|
||||
|
||||
template <class F, class IndexT>
|
||||
constexpr decltype(auto) c(F&& f, const Sptr<IndexT>& ind) const;
|
||||
|
||||
template <class IndexT>
|
||||
constexpr decltype(auto) c(const Sptr<IndexT>& ind) const;
|
||||
|
||||
template <class F, class... Args>
|
||||
constexpr decltype(auto) o(F&& f, Args&&... args) const;
|
||||
|
||||
};
|
||||
|
||||
template <class OpT>
|
||||
class OpInterface : public COpInterface<OpT>
|
||||
{
|
||||
public:
|
||||
typedef COpInterface<OpT> OI;
|
||||
|
||||
constexpr OpInterface() = default;
|
||||
|
||||
OpT& THIS() { return static_cast<OpT&>(*this); }
|
||||
const OpT& THIS() const { return static_cast<const OpT&>(*this); }
|
||||
|
||||
template <class IndexT, class F, class... Args>
|
||||
constexpr decltype(auto) ax(const Sptr<IndexT>& ind, F&& f, const Args&... args);
|
||||
|
||||
template <class IndexT, class F, class... Args>
|
||||
inline void a(const Sptr<IndexT>& ind, F&& f, const Args&... args);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_operation
|
||||
{ static constexpr bool value = std::is_base_of<COpInterface<T>,T>::value; };
|
||||
|
||||
template <class T>
|
||||
struct is_mutable_operation
|
||||
{ static constexpr bool value = std::is_base_of<OpInterface<T>,T>::value; };
|
||||
|
||||
template <class T>
|
||||
struct op_size
|
||||
{ static constexpr SizeT value = is_operation<T>::value ? 1 : 0; };
|
||||
|
||||
template <typename T, class IndexT>
|
||||
class COpRoot : public COpInterface<COpRoot<T,IndexT>>
|
||||
{
|
||||
public:
|
||||
typedef OpInterface<COpRoot<T,IndexT>> OI;
|
||||
|
||||
constexpr COpRoot() = default;
|
||||
|
||||
constexpr COpRoot(const CArrayBase<T>& a, const Sptr<IndexT>& ind);
|
||||
constexpr COpRoot(const T* data, const Sptr<IndexT>& ind);
|
||||
constexpr COpRoot& init(const T* data, const Sptr<IndexT>& ind);
|
||||
|
||||
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;
|
||||
|
||||
const T* data() const;
|
||||
|
||||
private:
|
||||
const T* mData = nullptr;
|
||||
Sptr<IndexT> mIndex;
|
||||
};
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr decltype(auto) coproot(const CArrayBase<T>& a, const Sptr<IndexT>& ind);
|
||||
|
||||
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>>
|
||||
{
|
||||
public:
|
||||
typedef OpInterface<OpCont<T,IndexT>> OI;
|
||||
typedef typename Container<T,index_const_size<IndexT>::value,
|
||||
index_has_const_size<IndexT>::value>::type CT;
|
||||
|
||||
constexpr OpCont() = default;
|
||||
|
||||
constexpr OpCont(const Sptr<IndexT>& ind);
|
||||
constexpr OpCont& init(const Sptr<IndexT>& ind);
|
||||
constexpr OpCont& init(const Sptr<IndexT>& ind, const Vector<T>& c);
|
||||
|
||||
constexpr decltype(auto) r();
|
||||
constexpr decltype(auto) r() const;
|
||||
|
||||
template <class Op>
|
||||
constexpr OpCont& operator=(const Op& in);
|
||||
|
||||
template <class Op>
|
||||
constexpr OpCont& operator+=(const Op& in);
|
||||
|
||||
constexpr OpCont& operator=(const OpCont& in);
|
||||
|
||||
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;
|
||||
|
||||
T* data();
|
||||
const T* data() const;
|
||||
|
||||
private:
|
||||
Sptr<IndexT> mIndex;
|
||||
CT mC;
|
||||
};
|
||||
|
||||
|
||||
template <typename T, class IndexT>
|
||||
class OpRoot : public OpInterface<OpRoot<T,IndexT>>
|
||||
{
|
||||
public:
|
||||
typedef OpInterface<OpRoot<T,IndexT>> OI;
|
||||
|
||||
constexpr OpRoot() = default;
|
||||
|
||||
constexpr OpRoot(ArrayBase<T>& a, const Sptr<IndexT>& ind);
|
||||
constexpr OpRoot(T* data, const Sptr<IndexT>& ind);
|
||||
constexpr OpRoot& init(T* data, const Sptr<IndexT>& ind);
|
||||
|
||||
template <class Op>
|
||||
constexpr OpRoot& operator=(const Op& in);
|
||||
|
||||
template <class Op>
|
||||
constexpr OpRoot& operator+=(const Op& in);
|
||||
|
||||
constexpr OpRoot& operator=(const OpRoot& in);
|
||||
|
||||
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;
|
||||
|
||||
T* data() const;
|
||||
|
||||
private:
|
||||
T* mData = nullptr;
|
||||
Sptr<IndexT> mIndex;
|
||||
|
||||
};
|
||||
|
||||
template <typename T, class IndexT>
|
||||
constexpr decltype(auto) oproot(ArrayBase<T>& a, const Sptr<IndexT>& ind);
|
||||
|
||||
template <class F, class... Ops>
|
||||
class Operation : public OpInterface<Operation<F,Ops...>>
|
||||
{
|
||||
public:
|
||||
typedef OpInterface<Operation<F,Ops...>> OI;
|
||||
|
||||
constexpr Operation() = default;
|
||||
|
||||
constexpr Operation(F&& f, const Ops&... ops);
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
template <SizeT... Is>
|
||||
constexpr decltype(auto) exec(std::index_sequence<Is...> is) const;
|
||||
|
||||
template <SizeT I, SizeT... Is>
|
||||
constexpr decltype(auto) rootStepsi(const IndexId<I>& id,
|
||||
std::index_sequence<Is...> is) const;
|
||||
|
||||
Tuple<Ops...> mOps;
|
||||
F mF;
|
||||
|
||||
};
|
||||
|
||||
template <class F, class... Ops>
|
||||
constexpr decltype(auto) operation(F&& f, const Ops&... ops);
|
||||
|
||||
template <class Tar, class Src>
|
||||
constexpr decltype(auto) assignxpr(const Tar& tar, const Src& src);
|
||||
|
||||
template <class Tar, class Src>
|
||||
constexpr decltype(auto) assignxpr(Tar& tar, const Src& src);
|
||||
|
||||
template <class F, class... Ops>
|
||||
struct op_size<Operation<F,Ops...>>
|
||||
{ static constexpr SizeT value = ( op_size<Ops>::value + ... ); };
|
||||
|
||||
template <class CXpr>
|
||||
class Contraction : public OpInterface<Contraction<CXpr>>
|
||||
{
|
||||
public:
|
||||
typedef OpInterface<Contraction<CXpr>> OI;
|
||||
|
||||
constexpr Contraction() = default;
|
||||
|
||||
constexpr Contraction(CXpr&& cxpr);
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
CXpr mCXpr;
|
||||
};
|
||||
|
||||
template <class CXpr>
|
||||
struct op_size<Contraction<CXpr>>
|
||||
{ static constexpr SizeT value = op_size<CXpr>::value; };
|
||||
|
||||
template <class F, class Op, class IndexT>
|
||||
constexpr decltype(auto) contraction(F&& f, Op&& op, const Sptr<IndexT>& i);
|
||||
|
||||
template <class IndexT>
|
||||
constexpr decltype(auto) indexOp(const Sptr<IndexT>& i);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,63 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/op_utility.cc.h
|
||||
@brief Operation utilities template implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_op_utility_cc_h__
|
||||
#define __cxz_op_utility_cc_h__
|
||||
|
||||
#include "op_utility.h"
|
||||
#include "xpr/pos_type.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
template <SizeT I, class PosT>
|
||||
constexpr decltype(auto) pos_get(const PosT& pos)
|
||||
{
|
||||
static_assert(I < static_pos_size<PosT>::value, "index out of range");
|
||||
if constexpr(I == 0){
|
||||
return pos;
|
||||
}
|
||||
else {
|
||||
return pos_get<I-1>(pos.next());
|
||||
}
|
||||
}
|
||||
|
||||
template <SizeT J, SizeT I, SizeT... Is>
|
||||
constexpr SizeT sum_index_sequence(std::index_sequence<I,Is...> is)
|
||||
{
|
||||
static_assert(J < sizeof...(Is)+1, "index out of range");
|
||||
if constexpr(J == 0){
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return sum_index_sequence<J-1>(std::index_sequence<Is...>{}) + I;
|
||||
}
|
||||
}
|
||||
|
||||
template <class F, class PosT, class OpTuple, class OpSizes, SizeT... Is>
|
||||
inline auto pos_unpack_args_i(const F& f, const PosT& pos, const OpTuple& args,
|
||||
OpSizes opsizes, std::index_sequence<Is...> is)
|
||||
{
|
||||
return f(std::get<Is>(args)(pos_get<sum_index_sequence<Is>(opsizes)>(pos))...);
|
||||
}
|
||||
|
||||
template <class F, class PosT, class... Ops>
|
||||
inline auto pos_unpack_args(const F& f, const PosT& pos, const Tuple<Ops...>& args)
|
||||
{
|
||||
static_assert(is_pos_type<PosT>::value, "got non-pos-type");
|
||||
static_assert((is_operation<Ops>::value and ...), "got non-operation type");
|
||||
typedef std::make_index_sequence<sizeof...(Ops)> Idxs;
|
||||
typedef std::index_sequence<op_size<Ops>::value...> OpSizes;
|
||||
return pos_unpack_args_i(f, pos, args, OpSizes{}, Idxs{});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/op_utility.h
|
||||
@brief Operation utilities declarations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_op_utility_h__
|
||||
#define __cxz_op_utility_h__
|
||||
|
||||
#include "base/base.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
template <SizeT I, class PosT>
|
||||
constexpr decltype(auto) pos_get(const PosT& pos);
|
||||
|
||||
template <SizeT J, SizeT... Is>
|
||||
constexpr SizeT sum_index_sequence(std::index_sequence<Is...> is);
|
||||
|
||||
template <class F, class PosT, class OpTuple, class OpSizes, SizeT... Is>
|
||||
inline auto pos_unpack_args_i(const F& f, const PosT& pos, const OpTuple& args,
|
||||
OpSizes opsizes, std::index_sequence<Is...> is);
|
||||
|
||||
template <class F, class PosT, class... Ops>
|
||||
inline auto pos_unpack_args(const F& f, const PosT& pos, const Tuple<Ops...>& args);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/operation.cc.h
|
||||
@brief Operation main header for template implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#include "op_types.cc.h"
|
||||
#include "op_utility.cc.h"
|
||||
#include "basic_operations.cc.h"
|
|
@ -1,16 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/operation/operation.h
|
||||
@brief Operation main header.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#include "op_types.h"
|
||||
#include "op_utility.h"
|
||||
#include "basic_operations.h"
|
||||
|
||||
#include "operation.cc.h"
|
94
src/include/operation_def.h
Normal file
94
src/include/operation_def.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
|
||||
#ifndef __operation_def_h__
|
||||
#define __operation_def_h__
|
||||
|
||||
#include "multi_array_operation.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <typename T, class OperationClass>
|
||||
auto operator+(const T& a, const OperationBase<T,OperationClass>& b)
|
||||
-> Operation<T,plus<T>,OperationValue<T>,OperationClass>
|
||||
{
|
||||
OperationValue<T> v(a);
|
||||
return Operation<T,plus<T>,OperationValue<T>,OperationClass>(v, b.THIS());
|
||||
}
|
||||
|
||||
template <typename T, class OperationClass>
|
||||
auto operator-(const T& a, const OperationBase<T,OperationClass>& b)
|
||||
-> Operation<T,minus<T>,OperationValue<T>,OperationClass>
|
||||
{
|
||||
OperationValue<T> v(a);
|
||||
return Operation<T,minus<T>,OperationValue<T>,OperationClass>(v, b.THIS());
|
||||
}
|
||||
|
||||
template <typename T, class OperationClass>
|
||||
auto operator*(const T& a, const OperationBase<T,OperationClass>& b)
|
||||
-> Operation<T,multiplies<T>,OperationValue<T>,OperationClass>
|
||||
{
|
||||
OperationValue<T> v(a);
|
||||
return Operation<T,multiplies<T>,OperationValue<T>,OperationClass>(v, b.THIS());
|
||||
}
|
||||
|
||||
template <typename T, class OperationClass>
|
||||
auto operator/(const T& a, const OperationBase<T,OperationClass>& b)
|
||||
-> Operation<T,divides<T>,OperationValue<T>,OperationClass>
|
||||
{
|
||||
OperationValue<T> v(a);
|
||||
return Operation<T,divides<T>,OperationValue<T>,OperationClass>(v, b.THIS());
|
||||
}
|
||||
|
||||
template <typename T, class OperationClass>
|
||||
auto operator+(const OperationBase<T,OperationClass>& a, const T& b)
|
||||
-> Operation<T,plus<T>,OperationClass,OperationValue<T> >
|
||||
{
|
||||
OperationValue<T> v(b);
|
||||
return Operation<T,plus<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
|
||||
}
|
||||
|
||||
template <typename T, class OperationClass>
|
||||
auto operator-(const OperationBase<T,OperationClass>& a, const T& b)
|
||||
-> Operation<T,minus<T>,OperationClass,OperationValue<T> >
|
||||
{
|
||||
OperationValue<T> v(b);
|
||||
return Operation<T,minus<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
|
||||
}
|
||||
|
||||
template <typename T, class OperationClass>
|
||||
auto operator*(const OperationBase<T,OperationClass>& a, const T& b)
|
||||
-> Operation<T,multiplies<T>,OperationClass,OperationValue<T> >
|
||||
{
|
||||
OperationValue<T> v(b);
|
||||
return Operation<T,multiplies<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
|
||||
}
|
||||
|
||||
template <typename T, class OperationClass>
|
||||
auto operator/(const OperationBase<T,OperationClass>& a, const T& b)
|
||||
-> Operation<T,divides<T>,OperationClass,OperationValue<T> >
|
||||
{
|
||||
OperationValue<T> v(b);
|
||||
return Operation<T,divides<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
|
||||
}
|
||||
|
||||
#define regFunc1(fff) template <typename T, class OperationClass> \
|
||||
auto fff(const OperationBase<T,OperationClass>& a) \
|
||||
-> Operation<T,x_##fff<T>,OperationClass> { \
|
||||
return Operation<T,x_##fff<T>,OperationClass>(a.THIS()); }
|
||||
|
||||
|
||||
#include "extensions/math.h"
|
||||
#undef regFunc1
|
||||
|
||||
|
||||
template <size_t N, typename T, class OperationClass>
|
||||
auto ipow(const OperationBase<T,OperationClass>& a)
|
||||
-> Operation<T,x_ipow<N-1>,OperationClass>
|
||||
{
|
||||
return Operation<T,x_ipow<N-1>,OperationClass>(a.THIS());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
46
src/include/operation_helper.h
Normal file
46
src/include/operation_helper.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
|
||||
#ifndef __operation_helper_h__
|
||||
#define __operation_helper_h__
|
||||
|
||||
#include "multi_array_operation.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <class BaseArray, class... Ranges>
|
||||
class PseudoArray
|
||||
{
|
||||
size_t mThreadNum;
|
||||
Slice<> mSl;
|
||||
mutable ConstOperationRoot<T,Range> mOp;
|
||||
|
||||
public:
|
||||
|
||||
template <class ET>
|
||||
const SrcHolder<ConstOperationRoot<T,Range>> operator[](ET pos) const;
|
||||
};
|
||||
|
||||
template <class Operation>
|
||||
class SrcHolder
|
||||
{
|
||||
|
||||
TempHolder operator+(SrcHolder in) const;
|
||||
// aso
|
||||
};
|
||||
|
||||
template <class Operation>
|
||||
class TempHolder
|
||||
{
|
||||
TempHolder operator+(SrcHolder in) const;
|
||||
TempHolder operator+(TempHolder in) const;
|
||||
};
|
||||
|
||||
template <class Operation>
|
||||
class TarHolder
|
||||
{
|
||||
TarHolder& operator=(TempHolder in);
|
||||
};
|
||||
|
||||
} // namespace MultiArrayTools
|
||||
|
||||
#endif
|
220
src/include/pack_num.h
Normal file
220
src/include/pack_num.h
Normal file
|
@ -0,0 +1,220 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
#ifndef __pack_num_h__
|
||||
#define __pack_num_h__
|
||||
|
||||
#include <cstdlib>
|
||||
//#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <ostream>
|
||||
|
||||
#include "base_def.h"
|
||||
#include "xfor/exttype.h"
|
||||
|
||||
namespace MultiArrayHelper
|
||||
{
|
||||
template <bool ISSTATIC>
|
||||
struct Application
|
||||
{
|
||||
template <class OpFunction, typename... Ts>
|
||||
static inline auto apply(std::shared_ptr<OpFunction> f, Ts... as)
|
||||
-> decltype((*f)(as...))
|
||||
{
|
||||
return (*f)(as...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Application<true>
|
||||
{
|
||||
template <class OpFunction, typename... Ts>
|
||||
static inline auto apply(std::shared_ptr<OpFunction> f, Ts... as)
|
||||
-> decltype(OpFunction::apply(as...))
|
||||
{
|
||||
return OpFunction::apply(as...);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <size_t N>
|
||||
struct PackNum
|
||||
{
|
||||
template <class MA, class ITuple, class... IPtrs>
|
||||
static auto mkElemOperation(const MA& ma, const ITuple& ituple, IPtrs... iptrs)
|
||||
-> decltype(PackNum<N-1>::mkElemOperation(ma, ituple, std::get<N>(ituple), iptrs...))
|
||||
{
|
||||
return PackNum<N-1>::mkElemOperation(ma, ituple, std::get<N>(ituple), iptrs...);
|
||||
}
|
||||
|
||||
|
||||
template <typename... T>
|
||||
static void printTuple(std::ostream& out, const std::tuple<T...>& tp)
|
||||
{
|
||||
out << std::get<sizeof...(T)-N-1>(tp) << ", ";
|
||||
PackNum<N-1>::printTuple(out, tp);
|
||||
}
|
||||
|
||||
template <class... Ops>
|
||||
static auto mkSteps(std::intptr_t ii, const std::tuple<Ops...>& otp)
|
||||
-> decltype(PackNum<N-1>::mkSteps(ii, otp).extend( std::get<N>(otp).rootSteps(ii)) )
|
||||
{
|
||||
return PackNum<N-1>::mkSteps(ii, otp).extend( std::get<N>(otp).rootSteps(ii));
|
||||
}
|
||||
|
||||
template <class RootStepTuple, class IndexClass, class OpClass>
|
||||
static void mkExt(std::array<RootStepTuple,IndexClass::totalDim()>& out,
|
||||
const std::array<std::intptr_t,IndexClass::totalDim()>& siar,
|
||||
const OpClass& second)
|
||||
{
|
||||
std::get<N>(out) = second.rootSteps( std::get<N>(siar) );
|
||||
PackNum<N-1>::mkExt(out, siar, second);
|
||||
}
|
||||
|
||||
template <size_t LAST, class ETuple, class OpTuple, class OpFunction, typename... Args>
|
||||
static inline auto mkOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, Args... args)
|
||||
{
|
||||
typedef typename std::remove_reference<decltype(std::get<N>(ops))>::type NextOpType;
|
||||
static_assert(LAST >= NextOpType::SIZE, "inconsistent array positions");
|
||||
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
|
||||
typedef decltype(std::get<N>(ops).get(Getter<NEXT>::template getX<ETuple>( pos ))) ArgT;
|
||||
return PackNum<N-1>::template mkOpExpr<NEXT,ETuple,OpTuple,OpFunction,ArgT,Args...>
|
||||
( f, pos, ops, std::get<N>(ops).get(Getter<NEXT>::template getX<ETuple>( pos )), args...);
|
||||
}
|
||||
|
||||
template <class OpTuple, class Expr>
|
||||
static auto mkLoop( const OpTuple& ot, Expr exp )
|
||||
-> decltype(std::get<N>(ot).loop( PackNum<N-1>::mkLoop(ot,exp) ))
|
||||
{
|
||||
return std::get<N>(ot).loop( PackNum<N-1>::mkLoop(ot,exp) );
|
||||
}
|
||||
|
||||
template <typename T, class Op, class... SRanges>
|
||||
static void mkSliceBlocks(std::array<size_t, sizeof...(SRanges)+1>& blocks,
|
||||
const ContainerIndex<T,typename SRanges::IndexType...>& index,
|
||||
const Op& op, size_t total = 1)
|
||||
{
|
||||
const size_t tmp =
|
||||
op.rootSteps(reinterpret_cast<std::intptr_t>
|
||||
( index.template getPtr<N>().get() ) )
|
||||
.val();
|
||||
std::get<N+1>(blocks) = tmp;
|
||||
PackNum<N-1>::template mkSliceBlocks<T,Op,SRanges...>(blocks, index, op, total * tmp);
|
||||
}
|
||||
|
||||
template <class... SRanges>
|
||||
static bool checkIfSameInstance(const std::tuple<std::shared_ptr<SRanges>...>& rtp1,
|
||||
const std::tuple<std::shared_ptr<SRanges>...>& rtp2)
|
||||
{
|
||||
return std::get<N>(rtp1).get() == std::get<N>(rtp2).get() and PackNum<N-1>::checkIfSameInstance(rtp1,rtp2);
|
||||
}
|
||||
|
||||
template <class MA, class ITuple, class... Indices>
|
||||
static inline auto mkMapOp(const MA& ma, const ITuple& itp, const std::shared_ptr<Indices>&... inds)
|
||||
-> decltype(PackNum<N-1>::mkMapOp(ma, itp, std::get<N>(itp), inds...))
|
||||
{
|
||||
return PackNum<N-1>::mkMapOp(ma, itp, std::get<N>(itp), inds...);
|
||||
}
|
||||
|
||||
template <size_t LAST,class OpTuple, class ETuple>
|
||||
static inline void setOpPos(OpTuple& ot, const ETuple& et)
|
||||
{
|
||||
typedef typename std::remove_reference<decltype(std::get<N>(ot))>::type NextOpType;
|
||||
static_assert(LAST >= NextOpType::SIZE, "inconsistent array positions");
|
||||
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
|
||||
std::get<N>( ot ).set( Getter<NEXT>::template getX<ETuple>( et ) );
|
||||
PackNum<N-1>::template setOpPos<NEXT,OpTuple,ETuple>(ot, et);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct PackNum<0>
|
||||
{
|
||||
template <class MA, class ITuple, class... IPtrs>
|
||||
static auto mkElemOperation(const MA& ma, const ITuple& ituple, IPtrs... iptrs)
|
||||
-> decltype(ma(iptrs...))
|
||||
{
|
||||
return ma(iptrs...);
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
static void printTuple(std::ostream& out, const std::tuple<T...>& tp)
|
||||
{
|
||||
out << std::get<sizeof...(T)-1>(tp);
|
||||
}
|
||||
|
||||
template <class... Ops>
|
||||
static auto mkSteps(std::intptr_t ii, const std::tuple<Ops...>& otp)
|
||||
-> decltype(std::get<0>(otp).rootSteps(ii))
|
||||
{
|
||||
return std::get<0>(otp).rootSteps(ii);
|
||||
}
|
||||
|
||||
template <class RootStepTuple, class IndexClass, class OpClass>
|
||||
static void mkExt(std::array<RootStepTuple,IndexClass::totalDim()>& out,
|
||||
const std::array<std::intptr_t,IndexClass::totalDim()>& siar,
|
||||
const OpClass& second)
|
||||
{
|
||||
std::get<0>(out) = second.rootSteps( std::get<0>(siar) );
|
||||
}
|
||||
|
||||
template <size_t LAST, class ETuple, class OpTuple, class OpFunction, typename... Args>
|
||||
static inline auto mkOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, const Args&... args)
|
||||
{
|
||||
typedef typename std::remove_reference<decltype(std::get<0>(ops))>::type NextOpType;
|
||||
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
|
||||
static_assert(NEXT == 0, "inconsistent array positions");
|
||||
typedef decltype(std::get<0>(ops).get(Getter<0>::template getX<ETuple>( pos ))) ArgT;
|
||||
return Application<OpFunction::FISSTATIC>::template apply<OpFunction,ArgT,Args...>(f, std::get<0>(ops).get(Getter<0>::template getX<ETuple>( pos )), args...);
|
||||
//return OpFunction::apply(std::get<0>(ops).get(Getter<0>::template getX<ETuple>( pos )), args...);
|
||||
}
|
||||
|
||||
template <class OpTuple, class Expr>
|
||||
static auto mkLoop( const OpTuple& ot, Expr exp )
|
||||
-> decltype(std::get<0>(ot).loop( exp ))
|
||||
{
|
||||
return std::get<0>(ot).loop( exp );
|
||||
}
|
||||
|
||||
template <typename T, class Op, class... SRanges>
|
||||
static void mkSliceBlocks(std::array<size_t, sizeof...(SRanges)+1>& blocks,
|
||||
const ContainerIndex<T,typename SRanges::IndexType...>& index,
|
||||
const Op& op, size_t total = 1)
|
||||
{
|
||||
const size_t tmp =
|
||||
op.rootSteps(reinterpret_cast<std::intptr_t>
|
||||
( index.template getPtr<0>().get() ) )
|
||||
.val();
|
||||
std::get<1>(blocks) = tmp;
|
||||
std::get<0>(blocks) = total * tmp; // this is not correct, but not used so far ... !!!
|
||||
}
|
||||
|
||||
template <class... SRanges>
|
||||
static bool checkIfSameInstance(const std::tuple<std::shared_ptr<SRanges>...>& rtp1,
|
||||
const std::tuple<std::shared_ptr<SRanges>...>& rtp2)
|
||||
{
|
||||
return std::get<0>(rtp1).get() == std::get<0>(rtp2).get();
|
||||
}
|
||||
|
||||
template <class MA, class ITuple, class... Indices>
|
||||
static inline auto mkMapOp(const MA& ma, const ITuple& itp, const std::shared_ptr<Indices>&... inds)
|
||||
-> decltype(ma.exec(std::get<0>(itp), inds...))
|
||||
{
|
||||
return ma.exec(std::get<0>(itp), inds...);
|
||||
}
|
||||
|
||||
template <size_t LAST,class OpTuple, class ETuple>
|
||||
static inline void setOpPos(OpTuple& ot, const ETuple& et)
|
||||
{
|
||||
typedef typename std::remove_reference<decltype(std::get<0>(ot))>::type NextOpType;
|
||||
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
|
||||
static_assert(NEXT == 0, "inconsistent array positions");
|
||||
std::get<0>( ot ).set( Getter<NEXT>::template getX<ETuple>( et ) );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace MultiArrayHelper
|
||||
|
||||
#endif
|
253
src/include/ranges/anonymous_range.h
Normal file
253
src/include/ranges/anonymous_range.h
Normal file
|
@ -0,0 +1,253 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
#ifndef __anonymous_range_h__
|
||||
#define __anonymous_range_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include "rbase_def.h"
|
||||
#include "ranges/range_base.h"
|
||||
#include "ranges/rpheader.h"
|
||||
#include "ranges/x_to_string.h"
|
||||
#include "ranges/type_map.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
typedef GenSingleIndex<size_t,SpaceType::ANON,MUI> AnonymousIndex;
|
||||
|
||||
//template <class R>
|
||||
//using SIZET = size_t;
|
||||
|
||||
typedef GenSingleRange<size_t,SpaceType::ANON,MUI> AnonymousRange;
|
||||
|
||||
// NOT THREAD SAVE!!
|
||||
class AnonymousRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
public:
|
||||
|
||||
typedef AnonymousRange oType;
|
||||
|
||||
AnonymousRangeFactory();
|
||||
|
||||
template <class... RangeTypes>
|
||||
AnonymousRangeFactory(const std::tuple<std::shared_ptr<RangeTypes>...>& origs);
|
||||
|
||||
template <class... RangeTypes>
|
||||
AnonymousRangeFactory(std::shared_ptr<RangeTypes>... origs);
|
||||
|
||||
AnonymousRangeFactory(const vector<std::shared_ptr<RangeBase>>& origs);
|
||||
|
||||
template <class Range>
|
||||
void append(std::shared_ptr<Range> r);
|
||||
|
||||
std::shared_ptr<RangeBase> create();
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<RangeBase> checkIfCreated(const vector<std::shared_ptr<RangeBase> >& pvec);
|
||||
|
||||
static std::map<std::shared_ptr<RangeBase>,vector<std::intptr_t> > mAleadyCreated;
|
||||
|
||||
bool mProductCreated = false;
|
||||
};
|
||||
|
||||
template <>
|
||||
class GenSingleRange<size_t,SpaceType::ANON,MUI> : public RangeInterface<AnonymousIndex>
|
||||
{
|
||||
public:
|
||||
|
||||
static constexpr bool defaultable = true;
|
||||
static constexpr size_t ISSTATIC = 0;
|
||||
static constexpr size_t SIZE = MUI;
|
||||
static constexpr bool HASMETACONT = false;
|
||||
|
||||
typedef RangeBase RB;
|
||||
typedef typename RangeInterface<AnonymousIndex>::IndexType IndexType;
|
||||
typedef GenSingleRange<size_t,SpaceType::ANON,MUI> RangeType;
|
||||
typedef size_t MetaType;
|
||||
typedef AnonymousRangeFactory FType;
|
||||
|
||||
virtual size_t size() const final;
|
||||
virtual size_t dim() const final;
|
||||
|
||||
size_t anonymousDim() const;
|
||||
size_t get(size_t pos) const;
|
||||
size_t getMeta(size_t metaPos) const;
|
||||
|
||||
virtual IndexType begin() const final;
|
||||
virtual IndexType end() const final;
|
||||
|
||||
virtual SpaceType spaceType() const final;
|
||||
virtual DataHeader dataHeader() const final;
|
||||
|
||||
virtual vector<size_t> typeNum() const final;
|
||||
virtual size_t cmeta(char* target, size_t pos) const final;
|
||||
virtual size_t cmetaSize() const final;
|
||||
virtual std::string stringMeta(size_t pos) const final;
|
||||
virtual vector<char> data() const final;
|
||||
|
||||
std::shared_ptr<RangeBase> sub(size_t num) const;
|
||||
|
||||
template <class Range>
|
||||
std::shared_ptr<Range> fullsub(size_t num) const;
|
||||
|
||||
template <class... Ranges>
|
||||
std::shared_ptr<MultiRange<Ranges...> > scast(SIZET<Ranges>... sizes) const; // save cast
|
||||
|
||||
const vector<std::shared_ptr<RangeBase> >& orig() const;
|
||||
|
||||
std::shared_ptr<AnonymousRange> sreplace(const std::shared_ptr<RangeBase> in, size_t num) const;
|
||||
std::shared_ptr<AnonymousRange> sreplace(const vector<std::shared_ptr<RangeBase>>& in, size_t num) const;
|
||||
std::shared_ptr<AnonymousRange> sreplace(const std::shared_ptr<RangeBase>& in,
|
||||
const vector<size_t>& num) const;
|
||||
|
||||
bool isEmpty() const;
|
||||
|
||||
friend AnonymousRangeFactory;
|
||||
|
||||
static AnonymousRangeFactory factory()
|
||||
{ return AnonymousRangeFactory(); }
|
||||
|
||||
protected:
|
||||
|
||||
GenSingleRange() = default;
|
||||
GenSingleRange(const AnonymousRange& in) = default;
|
||||
|
||||
template <class... RangeTypes>
|
||||
GenSingleRange(const std::tuple<std::shared_ptr<RangeTypes>...>& origs);
|
||||
|
||||
template <class... RangeTypes>
|
||||
GenSingleRange(std::shared_ptr<RangeTypes>... origs);
|
||||
|
||||
GenSingleRange(const vector<std::shared_ptr<RangeBase>>& origs);
|
||||
|
||||
size_t mSize = 1;
|
||||
bool mEmpty = true;
|
||||
|
||||
vector<std::shared_ptr<RangeBase> > mOrig;
|
||||
};
|
||||
}
|
||||
|
||||
/* ========================= *
|
||||
* --- TEMPLATE CODE --- *
|
||||
* ========================= */
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
/***********************
|
||||
* AnonymousRange *
|
||||
***********************/
|
||||
|
||||
template <class... RangeTypes>
|
||||
AnonymousRangeFactory::AnonymousRangeFactory(const std::tuple<std::shared_ptr<RangeTypes>...>& origs)
|
||||
{
|
||||
mProd = std::shared_ptr<oType>( new AnonymousRange( origs ) );
|
||||
}
|
||||
|
||||
template <class... RangeTypes>
|
||||
AnonymousRangeFactory::AnonymousRangeFactory(std::shared_ptr<RangeTypes>... origs)
|
||||
{
|
||||
mProd = std::shared_ptr<oType>( new AnonymousRange( origs... ) );
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
void AnonymousRangeFactory::append(std::shared_ptr<Range> r)
|
||||
{
|
||||
if(mProductCreated){
|
||||
|
||||
mProd = std::shared_ptr<oType>( new AnonymousRange( *std::dynamic_pointer_cast<oType>(mProd) ) );
|
||||
mProductCreated = false;
|
||||
}
|
||||
std::dynamic_pointer_cast<oType>(mProd)->mOrig.push_back(r);
|
||||
std::dynamic_pointer_cast<oType>(mProd)->mSize *= r->size();
|
||||
std::dynamic_pointer_cast<oType>(mProd)->mEmpty = false;
|
||||
}
|
||||
|
||||
/*****************
|
||||
* Functions *
|
||||
*****************/
|
||||
|
||||
std::shared_ptr<AnonymousRange> defaultRange(size_t size = 0);
|
||||
}
|
||||
|
||||
namespace MultiArrayHelper
|
||||
{
|
||||
using namespace MultiArrayTools;
|
||||
|
||||
template <>
|
||||
inline void resolveSetRange<AnonymousRange>(std::shared_ptr<AnonymousRange>& rp,
|
||||
const vector<std::shared_ptr<RangeBase> >& orig,
|
||||
size_t origpos, size_t size)
|
||||
{
|
||||
AnonymousRangeFactory arf;
|
||||
for(size_t op = origpos; op != origpos + size; ++op){
|
||||
//VCHECK(op);
|
||||
arf.append(orig[op]);
|
||||
}
|
||||
rp = std::dynamic_pointer_cast<AnonymousRange>( arf.create() );
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void setRangeToVec<AnonymousRange>(vector<std::shared_ptr<RangeBase> >& v,
|
||||
std::shared_ptr<AnonymousRange> r)
|
||||
{
|
||||
if(not r->isEmpty()){
|
||||
for(size_t i = r->anonymousDim(); i != 0; --i){
|
||||
v.insert(v.begin(), r->sub(i-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
/***********************
|
||||
* AnonymousRange *
|
||||
***********************/
|
||||
|
||||
template <class... RangeTypes>
|
||||
GenSingleRange<size_t,SpaceType::ANON,MUI>::GenSingleRange(const std::tuple<std::shared_ptr<RangeTypes>...>& origs) :
|
||||
RangeInterface<AnonymousIndex>()
|
||||
{
|
||||
RPackNum<sizeof...(RangeTypes)-1>::RangesToVec( origs, mOrig );
|
||||
mSize = RPackNum<sizeof...(RangeTypes)-1>::getSize( origs );
|
||||
if(sizeof...(RangeTypes)){
|
||||
mEmpty = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <class... RangeTypes>
|
||||
GenSingleRange<size_t,SpaceType::ANON,MUI>::GenSingleRange(std::shared_ptr<RangeTypes>... origs) :
|
||||
RangeInterface<AnonymousIndex>()
|
||||
{
|
||||
auto rst = std::make_tuple(origs...);
|
||||
RPackNum<sizeof...(RangeTypes)-1>::RangesToVec( rst, mOrig );
|
||||
mSize = RPackNum<sizeof...(RangeTypes)-1>::getSize( rst );
|
||||
if(sizeof...(RangeTypes)){
|
||||
mEmpty = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
std::shared_ptr<Range> GenSingleRange<size_t,SpaceType::ANON,MUI>::fullsub(size_t num) const
|
||||
{
|
||||
return std::dynamic_pointer_cast<Range>( mOrig.at(num) );
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
std::shared_ptr<MultiRange<Ranges...> > GenSingleRange<size_t,SpaceType::ANON,MUI>::scast(SIZET<Ranges>... sizes) const
|
||||
{
|
||||
std::tuple<std::shared_ptr<Ranges>...> rtp;
|
||||
RPackNum<sizeof...(Ranges)-1>::resolveRangeType(mOrig, rtp, 0, sizes...);
|
||||
MultiRangeFactory<Ranges...> mrf(rtp);
|
||||
return std::dynamic_pointer_cast<MultiRange<Ranges...> >( mrf.create() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
766
src/include/ranges/container_range.h
Normal file
766
src/include/ranges/container_range.h
Normal file
|
@ -0,0 +1,766 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
#ifndef __container_range_h__
|
||||
#define __container_range_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <tuple>
|
||||
#include <memory>
|
||||
|
||||
#include "ranges/range_base.h"
|
||||
#include "ranges/index_base.h"
|
||||
|
||||
#include "rpack_num.h"
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
|
||||
template <typename T, class... Indices>
|
||||
class ContainerIndex : public IndexInterface<ContainerIndex<T,Indices...>,
|
||||
std::tuple<typename Indices::MetaType...> >,
|
||||
public std::iterator<std::random_access_iterator_tag,T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef IndexInterface<ContainerIndex<T,Indices...>,
|
||||
std::tuple<typename Indices::MetaType...> > IB;
|
||||
typedef std::tuple<typename Indices::MetaType...> MetaType;
|
||||
typedef std::tuple<std::shared_ptr<Indices>...> IndexPack;
|
||||
typedef ContainerRange<T,typename Indices::RangeType...> RangeType;
|
||||
|
||||
static constexpr IndexType sType() { return IndexType::CONT; }
|
||||
static constexpr size_t sDim() { return sizeof...(Indices); }
|
||||
static constexpr size_t totalDim() { return mkTotalDim<Indices...>(); }
|
||||
|
||||
static constexpr SpaceType STYPE = SpaceType::ANY;
|
||||
static constexpr bool PARALLEL = std::tuple_element<0,std::tuple<Indices...>>::type::PARALLEL;
|
||||
|
||||
template <typename X>
|
||||
using CIX = ContainerIndex<X,Indices...>;
|
||||
|
||||
template <typename X>
|
||||
friend class CIX;
|
||||
|
||||
private:
|
||||
|
||||
ContainerIndex() = default;
|
||||
|
||||
bool mNonTrivialBlocks = false;
|
||||
bool mExternControl = false;
|
||||
IndexPack mIPack;
|
||||
std::array<size_t,sizeof...(Indices)+1> mBlockSizes;
|
||||
const T* mData = nullptr;
|
||||
size_t mCPos;
|
||||
//const MultiArrayBase<T,typename Indices::RangeType...>* mMa = nullptr;
|
||||
std::intptr_t mObjPtrNum;
|
||||
|
||||
public:
|
||||
|
||||
ContainerIndex(const ContainerIndex& in) = default;
|
||||
ContainerIndex& operator=(const ContainerIndex& in) = default;
|
||||
|
||||
ContainerIndex(const ContainerIndex& in, bool copy) :
|
||||
IB(in),
|
||||
mNonTrivialBlocks(in.mNonTrivialBlocks),
|
||||
mExternControl(false),
|
||||
mBlockSizes(in.mBlockSizes),
|
||||
mData(in.mData),
|
||||
mCPos(in.mCPos),
|
||||
mObjPtrNum(in.mObjPtrNum)
|
||||
{
|
||||
//if(copy){
|
||||
RPackNum<sizeof...(Indices)-1>::copyIndex(mIPack, in);
|
||||
//}
|
||||
//else {
|
||||
//mIPack = in.mIPack;
|
||||
//}
|
||||
}
|
||||
|
||||
ContainerIndex& copy(const ContainerIndex& in)
|
||||
{
|
||||
IB::operator=(in);
|
||||
mNonTrivialBlocks = in.mNonTrivialBlocks;
|
||||
mExternControl = false;
|
||||
mBlockSizes = in.mBlockSizes;
|
||||
mData = in.mData;
|
||||
mCPos = in.mCPos;
|
||||
mObjPtrNum = in.mObjPtrNum;
|
||||
RPackNum<sizeof...(Indices)-1>::copyIndex(mIPack, in);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
ContainerIndex& operator=(const ContainerIndex<X,Indices...>& in);
|
||||
|
||||
template <class MRange>
|
||||
ContainerIndex(const std::shared_ptr<MRange>& range,
|
||||
std::intptr_t objPtrNum);
|
||||
|
||||
template <class MRange>
|
||||
ContainerIndex(const std::shared_ptr<MRange>& range,
|
||||
std::intptr_t objPtrNum,
|
||||
const std::array<size_t,sizeof...(Indices)+1>& blockSizes);
|
||||
|
||||
template <size_t N>
|
||||
auto get() const -> decltype( *std::get<N>( mIPack ) )&;
|
||||
|
||||
template <size_t N>
|
||||
auto getPtr() const -> decltype( std::get<N>( mIPack ) )&;
|
||||
|
||||
template <size_t N>
|
||||
size_t getBlockSize() const { return std::get<N>(mBlockSizes); }
|
||||
|
||||
const IndexPack& pack() const { return mIPack; }
|
||||
|
||||
ContainerIndex& sync(); // recalculate 'IB::mPos' when externalControl == true
|
||||
ContainerIndex& operator()(const std::shared_ptr<Indices>&... inds); // control via external indices
|
||||
ContainerIndex& operator()(const std::tuple<std::shared_ptr<Indices>...>& inds);
|
||||
ContainerIndex& operator()(); // -> sync; just to shorten the code
|
||||
|
||||
// ==== >>>>> STATIC POLYMORPHISM <<<<< ====
|
||||
|
||||
IndexType type() const;
|
||||
|
||||
ContainerIndex& operator++();
|
||||
ContainerIndex& operator--();
|
||||
|
||||
ContainerIndex& operator=(size_t pos);
|
||||
|
||||
int pp(std::intptr_t idxPtrNum);
|
||||
int mm(std::intptr_t idxPtrNum);
|
||||
|
||||
std::string stringMeta() const;
|
||||
MetaType meta() const;
|
||||
ContainerIndex& at(const MetaType& metaPos);
|
||||
|
||||
size_t dim() const;
|
||||
bool first() const;
|
||||
bool last() const;
|
||||
bool sliceMode() const;
|
||||
|
||||
std::shared_ptr<RangeType> range();
|
||||
|
||||
template <size_t N>
|
||||
auto getPtr() -> decltype( std::get<N>( mIPack ) )&;
|
||||
|
||||
size_t getStepSize(size_t n);
|
||||
|
||||
std::string id() const;
|
||||
void print(size_t offset);
|
||||
|
||||
template <class Exprs>
|
||||
auto ifor(size_t step, Exprs exs) const
|
||||
-> decltype(RPackNum<sizeof...(Indices)-1>::mkFor(step, mIPack, mBlockSizes, exs));
|
||||
|
||||
template <class Exprs>
|
||||
auto iforh(size_t step, Exprs exs) const
|
||||
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh(step, mIPack, mBlockSizes, exs));
|
||||
|
||||
template <class Exprs>
|
||||
auto pifor(size_t step, Exprs exs) const
|
||||
-> decltype(RPackNum<sizeof...(Indices)-1>::mkPFor(step, mIPack, mBlockSizes, exs));
|
||||
|
||||
std::intptr_t container() const;
|
||||
ContainerIndex& format(const std::array<size_t,sizeof...(Indices)+1>& blocks);
|
||||
|
||||
// Iterator Stuff
|
||||
|
||||
ContainerIndex& setData(const T* data);
|
||||
|
||||
const T& operator*() const;
|
||||
const T* operator->() const;
|
||||
//T& operator*();
|
||||
//T* operator->();
|
||||
|
||||
ContainerIndex operator++(int);
|
||||
ContainerIndex operator--(int);
|
||||
ContainerIndex& operator+=(int diff);
|
||||
ContainerIndex& operator-=(int diff);
|
||||
ContainerIndex operator+(int num) const;
|
||||
ContainerIndex operator-(int num) const;
|
||||
|
||||
int operator-(const ContainerIndex& it) const;
|
||||
const T& operator[](int num) const;
|
||||
|
||||
bool operator<(const ContainerIndex& it) const;
|
||||
bool operator>(const ContainerIndex& it) const;
|
||||
bool operator<=(const ContainerIndex& it) const;
|
||||
bool operator>=(const ContainerIndex& it) const;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
template <typename T, class... Ranges>
|
||||
class ContainerRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ContainerRange<T,Ranges...> oType;
|
||||
|
||||
ContainerRangeFactory();
|
||||
ContainerRangeFactory(const std::shared_ptr<Ranges>&... rs);
|
||||
ContainerRangeFactory(const typename ContainerRange<T,Ranges...>::SpaceType& space);
|
||||
|
||||
virtual std::shared_ptr<RangeBase> create() override;
|
||||
|
||||
protected:
|
||||
|
||||
};*/
|
||||
/*
|
||||
template <typename T, class... Ranges>
|
||||
class ContainerRange : public RangeInterface<ContainerIndex<T,typename Ranges::IndexType...> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef RangeBase RB;
|
||||
typedef std::tuple<std::shared_ptr<Ranges>...> SpaceType;
|
||||
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
||||
|
||||
protected:
|
||||
ContainerRange() = default;
|
||||
ContainerRange(const ContainerRange& in) = delete;
|
||||
ContainerRange& operator=(const ContainerRange& in) = delete;
|
||||
|
||||
ContainerRange(const std::shared_ptr<Ranges>&... rs);
|
||||
ContainerRange(const SpaceType& space);
|
||||
|
||||
SpaceType mSpace;
|
||||
|
||||
public:
|
||||
static const size_t sdim = sizeof...(Ranges);
|
||||
|
||||
virtual size_t dim() const override;
|
||||
virtual size_t size() const override;
|
||||
|
||||
template <size_t N>
|
||||
auto get() const -> decltype( *std::get<N>( mSpace ) )&;
|
||||
|
||||
template <size_t N>
|
||||
auto getPtr() const -> decltype( std::get<N>( mSpace ) )&;
|
||||
|
||||
const SpaceType& space() const;
|
||||
|
||||
virtual IndexType begin() const override;
|
||||
virtual IndexType end() const override;
|
||||
|
||||
friend ContainerRangeFactory<T,Ranges...>;
|
||||
|
||||
static constexpr bool defaultable = false;
|
||||
static constexpr size_t ISSTATIC = SubProp<Ranges...>::ISSTATIC;
|
||||
static constexpr size_t SIZE = SubProp<Ranges...>::SIZE;
|
||||
};
|
||||
*/
|
||||
|
||||
//template <typename T, class... Ranges>
|
||||
//using ContainerRange = MultiRange<Ranges...>;
|
||||
|
||||
} // end namespace MultiArrayTools
|
||||
|
||||
/* ========================= *
|
||||
* --- TEMPLATE CODE --- *
|
||||
* ========================= */
|
||||
|
||||
namespace MultiArrayTools
|
||||
{
|
||||
namespace
|
||||
{
|
||||
using namespace MultiArrayHelper;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* ContainerIndex *
|
||||
**********************/
|
||||
|
||||
template <typename T, class... Indices>
|
||||
template <class MRange>
|
||||
ContainerIndex<T,Indices...>::ContainerIndex(const std::shared_ptr<MRange>& range,
|
||||
std::intptr_t objPtrNum) :
|
||||
IndexInterface<ContainerIndex<T,Indices...>,std::tuple<typename Indices::MetaType...> >(range, 0),
|
||||
mObjPtrNum(objPtrNum)
|
||||
{
|
||||
RPackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
|
||||
std::get<sizeof...(Indices)>(mBlockSizes) = 1;
|
||||
RPackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack);
|
||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
template <class MRange>
|
||||
ContainerIndex<T,Indices...>::ContainerIndex(const std::shared_ptr<MRange>& range,
|
||||
std::intptr_t objPtrNum,
|
||||
const std::array<size_t,sizeof...(Indices)+1>& blockSizes) :
|
||||
IndexInterface<ContainerIndex<T,Indices...>,std::tuple<typename Indices::MetaType...> >(range, 0),
|
||||
mObjPtrNum(objPtrNum)
|
||||
{
|
||||
RPackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
|
||||
mBlockSizes = blockSizes;
|
||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
|
||||
mNonTrivialBlocks = true;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
template <typename X>
|
||||
ContainerIndex<T,Indices...>&
|
||||
ContainerIndex<T,Indices...>::operator=(const ContainerIndex<X,Indices...>& in)
|
||||
{
|
||||
mIPack = in.mIPack;
|
||||
return (*this)();
|
||||
}
|
||||
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::sync()
|
||||
{
|
||||
if(mExternControl){
|
||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
|
||||
//VCHECK(id());
|
||||
//VCHECK(sizeof...(Indices));
|
||||
//assert(IB::mPos < IB::max());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
template <size_t N>
|
||||
auto ContainerIndex<T,Indices...>::get() const -> decltype( *std::get<N>( mIPack ) )&
|
||||
{
|
||||
return *std::get<N>( mIPack );
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
template <size_t N>
|
||||
auto ContainerIndex<T,Indices...>::getPtr() const -> decltype( std::get<N>( mIPack ) )&
|
||||
{
|
||||
return std::get<N>( mIPack );
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator()(const std::shared_ptr<Indices>&... inds)
|
||||
{
|
||||
RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, inds...);
|
||||
mExternControl = true;
|
||||
return sync();
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator()(const std::tuple<std::shared_ptr<Indices>...>& inds)
|
||||
{
|
||||
RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, inds);
|
||||
mExternControl = true;
|
||||
return sync();
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator()()
|
||||
{
|
||||
return sync();
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
IndexType ContainerIndex<T,Indices...>::type() const { return IndexType::CONT; }
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator++()
|
||||
{
|
||||
if(mExternControl){
|
||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||
}
|
||||
RPackNum<sizeof...(Indices)-1>::pp( mIPack );
|
||||
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
|
||||
++IB::mPos;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator--()
|
||||
{
|
||||
if(mExternControl){
|
||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack);
|
||||
}
|
||||
RPackNum<sizeof...(Indices)-1>::mm( mIPack );
|
||||
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
|
||||
--IB::mPos;
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator=(size_t pos)
|
||||
{
|
||||
IB::mPos = pos;
|
||||
RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, pos);
|
||||
mCPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
int ContainerIndex<T,Indices...>::pp(std::intptr_t idxPtrNum)
|
||||
{
|
||||
int tmp = RPackNum<sizeof...(Indices)-1>::pp(mIPack, mBlockSizes, idxPtrNum);
|
||||
IB::mPos += tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
int ContainerIndex<T,Indices...>::mm(std::intptr_t idxPtrNum)
|
||||
{
|
||||
int tmp = RPackNum<sizeof...(Indices)-1>::mm(mIPack, mBlockSizes, idxPtrNum);
|
||||
IB::mPos -= tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
std::string ContainerIndex<T,Indices...>::stringMeta() const
|
||||
{
|
||||
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr )->stringMeta(IB::mPos);
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
typename ContainerIndex<T,Indices...>::MetaType ContainerIndex<T,Indices...>::meta() const
|
||||
{
|
||||
MetaType metaTuple;
|
||||
RPackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, mIPack);
|
||||
return metaTuple;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::at(const MetaType& metaPos)
|
||||
{
|
||||
RPackNum<sizeof...(Indices)-1>::setMeta(mIPack, metaPos);
|
||||
IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
size_t ContainerIndex<T,Indices...>::dim() const
|
||||
{
|
||||
return sizeof...(Indices);
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
bool ContainerIndex<T,Indices...>::first() const
|
||||
{
|
||||
return IB::pos() == 0;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
bool ContainerIndex<T,Indices...>::last() const
|
||||
{
|
||||
return IB::pos() == IB::mMax - 1;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
bool ContainerIndex<T,Indices...>::sliceMode() const
|
||||
{
|
||||
return mNonTrivialBlocks;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
std::shared_ptr<typename ContainerIndex<T,Indices...>::RangeType>
|
||||
ContainerIndex<T,Indices...>::range()
|
||||
{
|
||||
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
template <size_t N>
|
||||
auto ContainerIndex<T,Indices...>::getPtr() -> decltype( std::get<N>( mIPack ) )&
|
||||
{
|
||||
return std::get<N>( mIPack );
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
size_t ContainerIndex<T,Indices...>::getStepSize(size_t n)
|
||||
{
|
||||
if(n >= sizeof...(Indices)){
|
||||
assert(0);
|
||||
// throw !!
|
||||
}
|
||||
return mBlockSizes[n+1];
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
std::string ContainerIndex<T,Indices...>::id() const
|
||||
{
|
||||
return std::string("con") + std::to_string(IB::mId);
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
void ContainerIndex<T,Indices...>::print(size_t offset)
|
||||
{
|
||||
if(offset == 0){
|
||||
std::cout << " === " << std::endl;
|
||||
}
|
||||
for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; }
|
||||
std::cout << id() << "[" << reinterpret_cast<std::intptr_t>(this) << "]"
|
||||
<< "(" << IB::mRangePtr << "): " << meta() << std::endl;
|
||||
RPackNum<sizeof...(Indices)-1>::printIndex(mIPack, offset+1);
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
template <class Exprs>
|
||||
auto ContainerIndex<T,Indices...>::ifor(size_t step, Exprs exs) const
|
||||
-> decltype(RPackNum<sizeof...(Indices)-1>::mkFor(step, mIPack, mBlockSizes, exs))
|
||||
{
|
||||
return RPackNum<sizeof...(Indices)-1>::mkFor(step, mIPack, mBlockSizes, exs);
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
template <class Exprs>
|
||||
auto ContainerIndex<T,Indices...>::iforh(size_t step, Exprs exs) const
|
||||
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh(step, mIPack, mBlockSizes, exs))
|
||||
{
|
||||
return RPackNum<sizeof...(Indices)-1>::mkForh(step, mIPack, mBlockSizes, exs);
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
template <class Exprs>
|
||||
auto ContainerIndex<T,Indices...>::pifor(size_t step, Exprs exs) const
|
||||
-> decltype(RPackNum<sizeof...(Indices)-1>::mkPFor(step, mIPack, mBlockSizes, exs))
|
||||
{
|
||||
return RPackNum<sizeof...(Indices)-1>::mkPFor(step, mIPack, mBlockSizes, exs);
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
std::intptr_t ContainerIndex<T,Indices...>::container() const
|
||||
{
|
||||
return mObjPtrNum;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::
|
||||
format(const std::array<size_t,sizeof...(Indices)+1>& blocks)
|
||||
{
|
||||
mBlockSizes = blocks;
|
||||
mNonTrivialBlocks = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::setData(const T* data)
|
||||
{
|
||||
mData = data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
const T& ContainerIndex<T,Indices...>::operator*() const
|
||||
{
|
||||
//return mMa[*this];
|
||||
return mData[mCPos];
|
||||
//return mData[IB::mPos];
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
const T* ContainerIndex<T,Indices...>::operator->() const
|
||||
{
|
||||
//return &mMa[*this];
|
||||
return &mData[mCPos];
|
||||
}
|
||||
/*
|
||||
template <typename T, class... Indices>
|
||||
T& ContainerIndex<T,Indices...>::operator*()
|
||||
{
|
||||
//return mMa[*this];
|
||||
return mData[IB::mPos];
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
T* ContainerIndex<T,Indices...>::operator->()
|
||||
{
|
||||
//return &mMa[*this];
|
||||
return &mData[IB::mPos];
|
||||
}
|
||||
*/
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...> ContainerIndex<T,Indices...>::operator++(int)
|
||||
{
|
||||
auto tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...> ContainerIndex<T,Indices...>::operator--(int)
|
||||
{
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator+=(int diff)
|
||||
{
|
||||
if(diff < 0){
|
||||
for(int i = 0; i != diff; ++i){
|
||||
(*this)--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(int i = 0; i != diff; ++i){
|
||||
(*this)++;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::operator-=(int diff)
|
||||
{
|
||||
if(diff < 0){
|
||||
for(int i = 0; i != diff; ++i){
|
||||
(*this)++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(int i = 0; i != diff; ++i){
|
||||
(*this)--;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...> ContainerIndex<T,Indices...>::operator+(int num) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += num;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
ContainerIndex<T,Indices...> ContainerIndex<T,Indices...>::operator-(int num) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= num;
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
int ContainerIndex<T,Indices...>::operator-(const ContainerIndex<T,Indices...>& it) const
|
||||
{
|
||||
return static_cast<int>( IB::mPos ) - static_cast<int>( it.pos() );
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
const T& ContainerIndex<T,Indices...>::operator[](int num) const
|
||||
{
|
||||
return mData[IB::mPos + num];
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
bool ContainerIndex<T,Indices...>::operator<(const ContainerIndex<T,Indices...>& it) const
|
||||
{
|
||||
return IB::mPos < it.pos();
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
bool ContainerIndex<T,Indices...>::operator>(const ContainerIndex<T,Indices...>& it) const
|
||||
{
|
||||
return IB::mPos > it.pos();
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
bool ContainerIndex<T,Indices...>::operator<=(const ContainerIndex<T,Indices...>& it) const
|
||||
{
|
||||
return IB::mPos <= it.pos();
|
||||
}
|
||||
|
||||
template <typename T, class... Indices>
|
||||
bool ContainerIndex<T,Indices...>::operator>=(const ContainerIndex<T,Indices...>& it) const
|
||||
{
|
||||
return IB::mPos >= it.pos();
|
||||
}
|
||||
|
||||
/*****************************
|
||||
* ContainerRangeFactory *
|
||||
*****************************/
|
||||
/*
|
||||
template <typename T, class... Ranges>
|
||||
ContainerRangeFactory<T,Ranges...>::ContainerRangeFactory(const std::shared_ptr<Ranges>&... rs)
|
||||
{
|
||||
mProd = std::shared_ptr<ContainerRange<T,Ranges...> >( new ContainerRange<T,Ranges...>( rs... ) );
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
ContainerRangeFactory<T,Ranges...>::
|
||||
ContainerRangeFactory(const typename ContainerRange<T,Ranges...>::SpaceType& space)
|
||||
{
|
||||
mProd = std::shared_ptr<ContainerRange<T,Ranges...> >( new ContainerRange<T,Ranges...>( space ) );
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
std::shared_ptr<RangeBase> ContainerRangeFactory<T,Ranges...>::create()
|
||||
{
|
||||
setSelf();
|
||||
return mProd;
|
||||
}
|
||||
*/
|
||||
/**********************
|
||||
* ContainerRange *
|
||||
**********************/
|
||||
/*
|
||||
template <typename T, class... Ranges>
|
||||
ContainerRange<T,Ranges...>::ContainerRange(const std::shared_ptr<Ranges>&... rs) :
|
||||
mSpace( std::make_tuple( rs... ) ) {}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
ContainerRange<T,Ranges...>::ContainerRange(const SpaceType& space) : mSpace( space ) {}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
size_t ContainerRange<T,Ranges...>::dim() const
|
||||
{
|
||||
return sizeof...(Ranges);
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
size_t ContainerRange<T,Ranges...>::size() const
|
||||
{
|
||||
return RPackNum<sizeof...(Ranges)-1>::getSize(mSpace);
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
template <size_t N>
|
||||
auto ContainerRange<T,Ranges...>::get() const -> decltype( *std::get<N>( mSpace ) )&
|
||||
{
|
||||
return *std::get<N>( mSpace );
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
template <size_t N>
|
||||
auto ContainerRange<T,Ranges...>::getPtr() const -> decltype( std::get<N>( mSpace ) )&
|
||||
{
|
||||
return std::get<N>( mSpace );
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
const typename ContainerRange<T,Ranges...>::SpaceType& ContainerRange<T,Ranges...>::space() const
|
||||
{
|
||||
return mSpace;
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
typename ContainerRange<T,Ranges...>::IndexType ContainerRange<T,Ranges...>::begin() const
|
||||
{
|
||||
ContainerIndex<T,typename Ranges::IndexType...>
|
||||
i( std::dynamic_pointer_cast<ContainerRange<T,Ranges...> >
|
||||
( std::shared_ptr<RangeBase>( RB::mThis ) ) );
|
||||
i = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
template <typename T, class... Ranges>
|
||||
typename ContainerRange<T,Ranges...>::IndexType ContainerRange<T,Ranges...>::end() const
|
||||
{
|
||||
ContainerIndex<T,typename Ranges::IndexType...>
|
||||
i( std::dynamic_pointer_cast<ContainerRange<T,Ranges...> >
|
||||
( std::shared_ptr<RangeBase>( RB::mThis ) ) );
|
||||
i = size();
|
||||
return i;
|
||||
}
|
||||
*/
|
||||
} // end namespace MultiArrayTools
|
||||
|
||||
|
||||
#endif
|
|
@ -1,44 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/ranges/crange.cc.h
|
||||
@brief CRange and CIndex template implementations.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_crange_cc_h__
|
||||
#define __cxz_crange_cc_h__
|
||||
|
||||
#include "crange.h"
|
||||
#include "index_mul.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
template <SizeT I>
|
||||
decltype(auto) CIndex::stepSize(const IndexId<I>& id) const
|
||||
{
|
||||
if constexpr(I != 0){
|
||||
return SPos<0>();
|
||||
}
|
||||
else {
|
||||
return UPos(id == this->id() ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Xpr, class F>
|
||||
decltype(auto) CIndex::ifor(const Xpr& xpr, F&& f) const
|
||||
{
|
||||
return For<0,Xpr,F>(this->pmax().val(), this->id(), xpr, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <class I>
|
||||
decltype(auto) operator*(const Sptr<CIndex>& a, const Sptr<I>& b)
|
||||
{
|
||||
return iptrMul(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,234 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/**
|
||||
|
||||
@file include/ranges/crange.h
|
||||
@brief CRange and CIndex declaration.
|
||||
|
||||
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||
Mail: chizeta@f3l.de
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __cxz_crange_h__
|
||||
#define __cxz_crange_h__
|
||||
|
||||
#include "base/base.h"
|
||||
#include "ranges/index_base.h"
|
||||
#include "ranges/range_base.h"
|
||||
#include "xpr/xpr.h"
|
||||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/** ****
|
||||
Specific index for CRange.
|
||||
*/
|
||||
class CIndex : public IndexInterface<CIndex,SizeT>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef IndexInterface<CIndex,SizeT> IB;
|
||||
typedef CRange RangeType;
|
||||
typedef SizeT MetaType;
|
||||
|
||||
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
|
||||
DEFAULT_MEMBERS(CIndex); /**< default constructors and assignments */
|
||||
|
||||
/** Construct index from range and position.
|
||||
@param range Range to iterate over.
|
||||
@param pos lexicographic position.
|
||||
*/
|
||||
CIndex(const RangePtr& range, SizeT pos = 0);
|
||||
|
||||
/** @copydoc IndexInterface::operator=(SizeT) */
|
||||
CIndex& operator=(SizeT lexpos);
|
||||
|
||||
/** @copydoc IndexInterface::operator++() */
|
||||
CIndex& operator++();
|
||||
|
||||
/** @copydoc IndexInterface::operator--() */
|
||||
CIndex& operator--();
|
||||
|
||||
/** @copydoc IndexInterface::operator+() */
|
||||
CIndex operator+(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-() */
|
||||
CIndex operator-(Int n) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator-(CIndex) */
|
||||
SizeT operator-(const CIndex& i) const;
|
||||
|
||||
/** @copydoc IndexInterface::operator+=() */
|
||||
CIndex& operator+=(Int n);
|
||||
|
||||
/** @copydoc IndexInterface::operator-=() */
|
||||
CIndex& 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*() */
|
||||
SizeT operator*() const;
|
||||
|
||||
/** @copydoc IndexInterface::dim() */
|
||||
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() */
|
||||
SizeT meta() const;
|
||||
|
||||
/** @copydoc IndexInterface::at() */
|
||||
CIndex& at(const SizeT& metaPos);
|
||||
|
||||
/** @copydoc IndexInterface::prange() */
|
||||
RangePtr prange(const CIndex& last) const;
|
||||
|
||||
/** @copydoc IndexInterface::deepFormat() */
|
||||
SizeT deepFormat() const;
|
||||
|
||||
/** @copydoc IndexInterface::deepMax() */
|
||||
SizeT deepMax() const;
|
||||
|
||||
/** @copydoc IndexInterface::reformat() */
|
||||
CIndex& reformat(const Vector<SizeT>& f, const Vector<SizeT>& s);
|
||||
|
||||
/** @copydoc IndexInterface::ifor() */
|
||||
template <class Xpr, class F = NoF>
|
||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||
|
||||
/** @copydoc IndexInterface::formatIsTrivial() */
|
||||
bool formatIsTrivial() const;
|
||||
|
||||
/** @copydoc IndexInterface::xpr() */
|
||||
COpRoot<SizeT,CIndex> xpr(const Sptr<CIndex>& _this) const;
|
||||
|
||||
private:
|
||||
Sptr<RangeType> mRangePtr;
|
||||
};
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
class CRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
public:
|
||||
typedef CRange oType;
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
CRangeFactory(SizeT size, RangePtr ref);
|
||||
|
||||
protected:
|
||||
virtual void make() override;
|
||||
|
||||
private:
|
||||
SizeT mSize;
|
||||
RangePtr mRef;
|
||||
};
|
||||
|
||||
/** ****
|
||||
Classic Range
|
||||
The parameter space is given by a
|
||||
set of positve integer numbers running
|
||||
form 0 to size-1
|
||||
*/
|
||||
class CRange : public RangeInterface<CRange>
|
||||
{
|
||||
public:
|
||||
typedef RangeBase RB;
|
||||
typedef CIndex IndexType;
|
||||
typedef SizeT MetaType;
|
||||
typedef CRangeFactory FType;
|
||||
|
||||
friend CRangeFactory;
|
||||
|
||||
virtual SizeT size() const override final;
|
||||
virtual SizeT dim() const override final;
|
||||
virtual String stringMeta(SizeT pos) const override final;
|
||||
virtual const TypeInfo& type() const override final;
|
||||
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
|
||||
*/
|
||||
SizeT get(SizeT pos) const;
|
||||
|
||||
/** return position for given meta data
|
||||
@param metaPos meta data, size type
|
||||
*/
|
||||
SizeT getMeta(SizeT metaPos) const;
|
||||
|
||||
protected:
|
||||
|
||||
/** default constructor */
|
||||
CRange() = default;
|
||||
|
||||
CRange(const CRange& in) = delete;
|
||||
|
||||
/** create range of given size
|
||||
@param size, input size, size type
|
||||
*/
|
||||
CRange(SizeT size);
|
||||
|
||||
virtual Vector<Uuid> key() const override final;
|
||||
|
||||
SizeT mSize = 0; /**< range size */
|
||||
|
||||
SERIALIZATION_FUNCTIONS_NOPUB;
|
||||
};
|
||||
|
||||
/** ***
|
||||
Specialize RangeCast for casts to CRange
|
||||
@see RangeCast
|
||||
*/
|
||||
template <>
|
||||
struct RangeCast<CRange>
|
||||
{
|
||||
/** cast the range */
|
||||
static Sptr<CRange> func(const RangePtr& r);
|
||||
};
|
||||
|
||||
/** ***
|
||||
CIndex can be used as expression
|
||||
@see index_expression_exists
|
||||
*/
|
||||
template <>
|
||||
struct index_expression_exists<CIndex>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue