Commit 6d6a575a authored by thomas.forbriger's avatar thomas.forbriger
Browse files

[MERGE] (master|vendor_Seitosh): vendor import of 23.10.2015

Merge branch 'vendor_Seitosh'


Commands executed on branch master (as a guideline for future imports):

  git merge -X theirs vendor_Seitosh
  git rm contrib/*/README.export
  git commit
parents 02cfa44c 25190a67
......@@ -2,7 +2,7 @@ this is <COPYING>
$Id: COPYING 4964 2013-02-01 13:27:42Z lrehor $
Copyright (C) 2002 by Thomas Forbriger and Wolfgang Friederich
......@@ -3,7 +3,7 @@
* ----------------------------------------------------------------------------
* $Id: Carray.h 3957 2011-05-16 14:46:43Z tforb $
* $Id$
* \author Thomas Forbriger
* \date 14/05/2011
......@@ -40,7 +40,7 @@
"$Id: Carray.h 3957 2011-05-16 14:46:43Z tforb $"
# this is <Makefile>
# ----------------------------------------------------------------------------
# $Id: Makefile 4964 2013-02-01 13:27:42Z lrehor $
# $Id$
# Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
......@@ -24,19 +24,10 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# ----
# A note on header files:
# We extensively comment class declarations within the header files. The
# reduce compilation time when using the library code, comments will be
# stripped from the header files that are exportet. These stripped versions
# are placed in the source code path with name *.h.strip and will be linked to
# INCINSTALLPATH with name *.h.
# Please have a look at the README file coming along with the source code in
# this directory for further notes regarding provided functionality,
# prerequisites and installation.
# Although comment stripping could be done by perl with an elaborate regular
# expression, we prefer the remcmmnt command by Jari Laaksonen. You can find
# the code at
# If it is not available to you, you should set TF_REMCMMNT=cat (see below)
# 06/12/2002 V1.0 Thomas Forbriger
# 27/12/2002 V1.1 doxygen reads Fortran code and files generated by f2c
......@@ -52,24 +43,9 @@
# 17/01/2011 V1.9 distinguish library creation and installation
# 27/07/2011 V1.10 give precedence to $LOCINCLUDEDIR over
# 26/01/2014 eliminate comment stripping
# ============================================================================
# environment variables
# ---------------------
# You will like to set the following environment variables:
# LOCINCLUDEDIR Defines the path where header files will be copied for
# usage in your own projects. You will pass this path to
# the precompiler with the -I option.
# LOCLIBDIR Defines the path where the binary library will be
# placed.
# TF_WWWBASEDIR Defines the path to your personal homepage. That's the
# place where doxygen output will be written too (see
# below).
# You will find the installed library header files in $(LOCINCLUDEDIR)/aff
include ../Makefile_var
......@@ -113,36 +89,19 @@ SRC=lib/ lib/ lib/ \
# test programs are placed in a subdirectory
TESTS=$(wildcard tests/*.cc)
# whereever we find a README, we will use it
README=$(shell find . -name README) README.changelog README.groups
README=$(shell find . -name README)
# the frame of doxygen documentation is palced in text files
DOXYTXT=$(shell find . -name doxygen\*.txt)
# place where we will copy header files
# place where we will copy the binary library
# name of headers with comments stripped off (these are linked to your include
# directory)
STRIPHEADER=$(addsuffix .strip,$(notdir $(HEADERS)))
# name of installed (exported) header files (these are the names in your
# include directory)
INSTHEADER=$(addprefix $(INCINSTALLPATH)/,$(filter-out ./tests/%,$(HEADERS)))
# comments can be removed from headers
# ------------------------------------
# if defined, empty lines are kept in comment-stripped headers
# to synchronize line numbers (necessary during library debugging)
# define this to be cat in case you do not have remcmmnt available
# compiler and preprocessor flags
# -------------------------------
......@@ -159,8 +118,8 @@ CPPFLAGS=$(addprefix -I,$(LOCINCLUDEDIR) $(subst :, ,$(SERVERINCLUDEDIR))) \
# files which are to be edited
flist: Makefile tests/Makefile doxydoc.cfg $(README) COPYING \
$(HEADERS) $(SRC) $(TESTS) $(wildcard doxy*.cfg) \
tests/ tests/f77procs.f
$(HEADERS) $(SRC) $(TESTS) $(wildcard doxy*.cfg) $(DOXYTXT) \
tests/ tests/f77procs.f $(TF_EDIT)
echo $(filter-out lib/% tests/%,$^) | tr ' ' '\n' | sort > $@
echo $(filter lib/%,$^) | tr ' ' '\n' | sort >> $@
echo $(filter tests/%,$^) | tr ' ' '\n' | sort >> $@
......@@ -177,8 +136,7 @@ clean: ;
-find . -name \*.bak | xargs --no-run-if-empty /bin/rm -v
-find . -name \*.o | xargs --no-run-if-empty /bin/rm -v
-find . -name \*.d | xargs --no-run-if-empty /bin/rm -v
-find . -name \*.h.strip | xargs --no-run-if-empty /bin/rm -v
-/bin/rm -vf flist *.o install-include libcontxx.a *.xxx junk* *.a *.so
-/bin/rm -vf flist *.o install-include *.xxx junk* *.a *.so
cd tests; $(MAKE) clean
......@@ -218,35 +176,12 @@ include $(patsubst,%.d,$(SRC))
# header files
# ------------
# Since we extensively document the class structures within the header files,
# these should be stripped for the production version (otherwise the compiler
# has to scan all comments on each compile). Stripping is done by the rule
# below and is controlled by the variables TF_REMCMMNT and EMPTYPRINT (see
# above).
# comment stripping
# -----------------
# awk rule assumes that the first non-comment line starts with '#'
# and that the first (copyright) comment end with pattern "^ */"
%.h.strip: %.h
awk 'BEGIN {hot=1;} /^ \*\// { if (hot) { hot=2; print; next;} }\
/^#/ { hot=0; } \
{ if (hot==2) { print ""; } else if (hot) { print; } }' $< > $@
$(TF_REMCMMNT) $< | awk 'BEGIN {hot=0;} \
/^ *$$/ { if ((hot) && ($(EMPTYPRINT))) { print ""; } next; } \
/^#/ { hot=1; } { if (hot) print; }' >> $@
.PRECIOUS: %.h.strip
$(INCINSTALLPATH)/%.h: %.h.strip
mkdir -vp $(dir $@)
-rm -fv $@
/bin/cp -vpd $< $@
@mkdir -vp $(dir $@)
-@rm -fv $@
@/bin/cp -vpd $< $@
# install header files
.PHONY: install-include
......@@ -292,7 +227,7 @@ DOXYWWWPATH=$(TF_WWWBASEDIR)/libaff
doxyclean: ;/bin/rm -rfv $(TF_WWWBASEDIR)/libaff
tests/f77procs.P tests/f77procs.f \
tests/ tests/f77common_com.P
/*! \file libaff/README
* \brief C++ containers for numbers (libaff)
* ----------------------------------------------------------------------------
* $Id: README 4964 2013-02-01 13:27:42Z lrehor $
* Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
* ----
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* ----
* C++ containers for numbers (libaff)
* This file contains:
* - documentation of namespace aff
* - mainpage text
* - documentation for pages:
* - \ref page_design
* - \ref page_using
* - \ref page_notes
* - \ref page_naming
* - 06/12/2002 V1.0 Thomas Forbriger (copied from libcontxx)
* - 20/12/2002 V1.1 (thof)
* - complete revision of this file
* - there are major gaps in
* -# \ref sec_design_multidimensional
* -# \ref page_using
* - 28/12/2002 V1.2 (thof)
* - new term for containers of const elements
* - added documentation regarding the concept of
* const correctness
* - added documentation regarding member typedefs
* - 29/12/2002 V1.3 (thof)
* - added section about replicated shared heap base
* class (\ref sec_design_replicated)
* - added section about sparse interface
* (\ref sec_design_interface_sparse)
* - added section about accessing internals
* (\ref sec_design_interface_internals)
* - reflect changes to Subarray and Slice
* - tell about class hierarchies and member data vs.
* inheritance
* - 04/01/2003 V1.4 (thof)
* - added section about Tcontainer typedef
* (\ref sec_design_interface_tcontainer)
* - 10/02/2004 V1.5 (thof)
* - added section about decision against interface
* base classes
* (\ref sec_design_interface_nobaseclass)
* - 10/11/2010 V1.6 (thof)
* - code fragments for precompiled templates are
* removed from the library (\ref sec_design_binary)
* - 14/05/2011 V1.7 (thof)
* - add info on raw-major and column-major order
* - 15/05/2011 V1.8 (thof)
* - reordered documentation, movde modules to
* README.groups
* ============================================================================
/*! \brief Root namespace of library
This namespace contains all modules of the library
(see \ref sec_main_modules).
Here you should find all components, the user needs to work with this
namespace aff {
} // namespace aff
/*! \mainpage
\author Thomas Forbriger
\author Wolfgang Friederich
\since December 2002
\date December 2002
\version V1.0
$Id: README 4964 2013-02-01 13:27:42Z lrehor $
Contents of this page:
- \ref sec_main_aims
- \ref sec_main_need
- \ref sec_main_peculiar
- \ref sec_main_modules
Additional information:
- \ref page_changelog
- \ref page_project_status
- \ref page_using
- \ref page_array_layout
- \ref page_design
- \ref page_naming
- \ref page_representation
- \ref page_fortran
\section sec_main_aims Aims of the library
The AFF (Array of Friederich and Forbriger) is a lightweight class library.
It offers a simple and easy to use container for numbers as is necessary in
numerical code. The offered array always has a rectangular strided layout,
reference semantics (through counted references) and a Fortran layout in
memory. The interface is intentionally kept sparse to keep compilation times
small. The array itself is meant to be used to pass numbers from one program
module to the other. If you want to exploit the power of expression
templates, pass the array contents to something like Blitz++.
Contents of this page:
\section sec_main_peculiar Peculiarities of AFF
\par Containers use counted references
All containers (e.g. aff::Array, aff::Series) use counted references to access
global memory. Assigning one container object to another just assigns the
reference. Both will use the same data in memory afterwards.
\sa \ref page_representation.
\par Const-correctness for array elements
In this library we follow provide functionality to write const-correct code
with regard to the array container and with regard to its element values.
\sa \ref sec_design_const.
\par Multidimensional arrays
Every aff::Array of this class has aff::Strided::Mmax_dimen dimensions.
Construction and access for lower dimensionality is provided. In the case of
using less dimensions, the size of the unused dimensions is 1 by default and
its index is inherently set to the first index.
\sa \ref sec_design_multidimensional.
\section sec_main_need Why do we need this array library
One major reason for replacing Fortran77 by C++ in numerical code is the
convenience in expressing logistics. Data of different type and size may be
packed into classes and encapsulated from the outside world. Most numerical
results are to be stored in arrays, multi-dimensional arrays in particular.
This library provides the basic functionality for storing many data of the
same type in memory, passing them around between subroutines in an efficient
way and accessing them through convenient interfaces. The main purpose of
this library is not calculation but managing (passing between program
modules, selection of subsets of the data) large amounts of numbers. In the
future it might provide interfaces to libraries like blitz++ for finite
difference calculations, MTL for linear algebra calculations, and POOMA for
parallel computations.
\section sec_main_modules Modules of the library
The main module is the array class aff::Array. It provides basic
functionality through its interface. See the explanation there.
It is presented in aff/array.h
The object code is placed in libaff.a.
\sa \ref group_array, \ref group_array_extensions
/*! \page page_design Design decisions
Contents of this page:
- \ref sec_design_interface
- \ref sec_design_interface_sparse
- \ref sec_design_interface_typedef
- \ref sec_design_interface_tcontainer
- \ref sec_design_interface_internals
- \ref sec_design_interface_nobaseclass
- \ref sec_design_threeclasses
- \ref sec_design_hierarchy
- \ref sec_design_replicated
- \ref sec_design_replicated_fact
- \ref sec_design_replicated_problem
- \ref sec_design_replicated_solution
- \ref sec_design_copy
- \ref sec_design_namespaces
- \ref sec_design_binary
- \ref sec_design_multidimensional
- \ref sec_design_const
- \ref sec_design_const_problem
- \ref sec_design_const_approach
- \ref sec_design_const_alternatives
- \ref sec_design_const_general
\section sec_design_interface Common interface concepts
\subsection sec_design_interface_sparse Sparse interfaces
The class library is intended to be a light-weight library. This means it
should offer basic functionality in terms of multidimensional containers
with counted references (and not more in first place). We do not like to
include a tremendous amount of code for specialized concepts (like subranges
or expression templates in Blitz++) each time we just need a small array.
Thus the header files providing array declarations (aff/array.h and the
files included therein) should be as sparse as possible. All extra
functionality like iterators (aff::Iterator presented in aff/iterator.h) or
slices (aff::Slice presented in aff/slice.h) should be external to the
aff::Array class. This allows us to load their definitions only where
needed. However, this approach requires that the internals of aff::Array are
exposed to the outside through appropriate functions (see
\ref sec_design_interface_internals).
\subsection sec_design_interface_typedef Member typedefs
Class templates like aff::Iterator may be used with any container class,
that provides an appropriate interface. This interface convention concerns
the access to the type of related objects. I will explain by example:
We use an iterator \c i which was declared
\code aff::Iterator<Cont> i \endcode
for a container of type \c Cont, it expects to find a corresponding
container class that promises constness of the elements through
\code Cont::Tcontainer_of_const \endcode
or short
\code Cont::Tcoc \endcode
For aff::ConstArray the type aff::ConstArray::Tcoc is just the class itself.
However aff::Array::Tcoc gives an aff::ConstArray.
\sa aff::SharedHeap::Tcontainer_of_const
\sa aff::ConstSharedHeap::Tcontainer_of_const
\sa aff::Array::Tcontainer_of_const
\sa aff::ConstArray::Tcontainer_of_const
\sa aff::Series::Tcontainer_of_const
\sa aff::ConstSeries::Tcontainer_of_const
In the same way we may access the appropriate element type through
\code Cont::Tvalue \endcode
which is \c T for aff::Array<T> and \c const \T for aff::ConstArray<T>.
However a
\code Cont::Tconst_value \endcode
will always provide a type with const qualifier.
\sa aff::Array::Tvalue
\sa aff::Array::Tconst_value
\sa aff::ConstArray::Tvalue
\sa aff::ConstArray::Tconst_value
\sa aff::Series::Tvalue
\sa aff::Series::Tconst_value
\sa aff::ConstSeries::Tvalue
\sa aff::ConstSeries::Tconst_value
In the same way we may access the type of the appropriate representation
by \code Cont::Trepresentation \endcode
\sa aff::Array::Trepresentation
\sa aff::ConstArray::Trepresentation
\sa aff::Series::Trepresentation
\sa aff::ConstSeries::Trepresentation
\b Notice: Using these typedefs (and also the typedefs for the shape class,
etc.) improves the maintainability of your code. Think of using the $HOME
variable in shell scripts. Once the name of your home directory changes, you
need not modify all your shell scripts. Now consider one day your shape
class might be renamed...
\subsection sec_design_interface_tcontainer Member typedef Tcontainer
\par Design decision:
Every class that can be converted to a container type, should provide a
member typedef \c Tcontainer and an appropriate conversion operator.
\sa aff::util::Slice
\sa aff::util::Subarray
\sa aff::deepcopy
\par Background
aff::deepcopy is a good example for function designed to deal with any
container. There may be others in the future, like global arithmetic
operators or sum-reduction. Due to its generality the function template puts
no restrictions on its template arguments. You may instantiate that template
for any class. In some sense this is bad practice and we have to resolve
ambiguities and support type conversions. In particular, think of feeding a
subarray (class aff::util::Subarray) to one of these whole-array functions
(this might be one of the most interesting uses). aff::util::Subarray easily
matches the template parameter, but does not offer the member functions
necessary for element access.
Hence we must ensure conversion of the aff::util::Subarray to its container
class. In our concept this is done with in aff::deepcopy. It looks for a
Tcontainer typedef in the argument class definitions and converts the class
objects to its corresponding container class before the copy operation.
Barton and Nackman propose another concept. Using their scheme we would
introduce a general Container class,
template<class C>
class Container {
typedef C& Tcontainer_reference;
Container(Tcontainer_reference c): M(c) { }
operator Tcontainer_reference() { return(M); }
Tcontainer_reference M;
that takes a special container class as
a template argument and initializes a member data reference to an object of
this class in its constructors. We would then derive aff::Array from this
class by
template<class T>
class Array: public Container<Array <T> > { };
This way any reference to a container (aff::Array, aff:Series,
aff::ConstArray, etc.) can be converted to a Container class object, which
agein offers a conversion operator to a reference to its leaf class.
Container-specific functions then are declared
template<class S, class T>
void deecopy(const Container<S>& source, Container<T>& target);
deepcopy than can only be called for objects that are derived from
\par Trade-offs
The Barton and Nackman trick involves another member data field in each
container class to hold the reference in the Container base class.
aff::Array would have to extra member data fields, because aff::Array and
aff::ConstArray both must inherit from Container. I regard this as a partial
violation to our concept of sparse interfaces. and small data types and
discard this option.
However, our concept requires to create a full copy of at least the target
container in each whole-array operation. This would not be necessary
generally. Generally we would operate directly on the aff::Array reference
passed as target of the operation.
With the Barton and Nackman trick this copy operation would only be
necessary with class objects, that are not directly derived from Container,
as are aff::util::Subarray and companions. However, for those we would have
to introduce specializations (overloaded functions) of whole-array
operations, that first perform the conversion (creating an aff::Array or
else) and then call the function that takes Container arguments.
\par Alternative
The cheapest alternative (with respect to runtime overhead in the
whole-array function and in the container classes aff::Array, etc.) is to
delegate the problem to aff::util::Subarray and companions. We could
introduce a member data field in them of type Tarray. This would allow for a
member function returning a reference to this member. There should be no
runtime overhead, since every subarray must once be converted to an array to
be useful (now this conversion takes place outside aff::util::Subarray).
But this would involve the inconvenience to call an extra member function in
Subarray, when passing to a whole-array function.
The template argument type of the corresponding whole-array function remains
unrestricted (totally unchecked).
\subsection sec_design_interface_internals Accessing internals
Providing extended functionality outside of aff::Array (see
\ref sec_design_interface_sparse) requires, that aff::Array,
aff::ConstArray, aff::Series, and aff::ConstSeries expose some of their
internals. This concerns the underlying shape as well as the represented
aff::ConstArray and aff::ConstSeries provide a read-only reference to the
data (i.e. an aff::ConstSharedHeap object) through their member-functions
aff::ConstArray::representation and
aff::ConstSeries::representation, respectively.
In the same way aff::Array and aff::Series return an aff::SharedHeap through
their representation member function.
All of them return a copy of their shape through the member functions
aff::Array::shape, aff::ConstArray::shape, aff::Series::shape, and
aff::ConstSeries::shape, respectively. The type of the appropriate shape is
available through a member typedef (see \ref sec_design_interface_typedef).
In return all containers provide a constructor that takes a representation
and a shape object and checks for their consistency.
\subsection sec_design_interface_nobaseclass Decision against a base class to express common interface
This library contains different classes that provide common interfaces. For
example all aff::ConstArray, aff::Array, aff::Series and aff::ConstSeries
provide the necessary interface to be used together with aff::Iterator or
aff::Browser. A rather elegant way to express this commonality in a template
context is the Barton and Nackman trick. All containers that can work
together with aff::Iterater sould have to inherit from a class
aff::Iteratable. The base class is templated, takes the iteratable class as
template parameter and stores a reference to the instance of the iteratable
class. This way each iteratable class can be converted to aff::Iteratable,
which again returns a reference to the classes iteratable features in the
appropriate context.
This way of expressing common interfaces makes the whole classes more
complicated than necessary to provide their elementary functionality. We
have to store an extra reference to the leaf class object for each feature,
we will express this way. And we have to include a whole bunsch of extra
code for each feature. Since we prefer \ref sec_design_interface_sparse this
method was rejected.
\section sec_design_threeclasses Three classes for one container
One container class like aff::Array or aff::Series is made up from its class
definition together with two other classes like the representation in
aff::SharedHeap and a shape like aff::Strided or aff::LinearShape.
Why not put all this functionality within one class like aff::Array?
-# aff::Array and aff::Series are class templates because they shall be
provided for any element type the user desires.
Consequently for each element type in use a separate instantiation of
this template class must be compiled.
The code describing the shape of the memory layout and the way index
values to raw memory have to be calculated is completely independent from
the element type of the container.
The shapes code can be compiled once for all template instantiations
For this reason it is efficient to provide this code in a separate class.
-# The containers in this library use reference counted pointers to raw
This way they share data in memory.
The default way to copy containers is a shallow copy, where only a
reference is copied (see \ref page_representation).
Using a seperate class aff::SharedHeap to handle these reference counted
pointers allows us to share memory between containers of different types,
i.e. an aff::Series<T> and an aff::Array<T>.
\section sec_design_hierarchy Class hierarchy: member data vs. inheritance
Containers like aff::Array rely on functionality provided by other classes.
They are based on shapes like aff::Strided and memory representations like
aff::SharedHeap (see \ref page_representation).
\par An array isn't a shape.
Thus it would look like better design to use shapes as member data.
We prefer, \b however, to derive privately from the shape classes.
This hides them from the outside (apart from explicit access -
see \ref sec_design_interface_internals).
At the same time we make use of using declarations to provide access to
member functions like aff::Strided::size() that make also sense as a member
of aff::Array.
\par An array is some kind of memory representation.
Thus it would look like proper design to derive an array from a
representation class.
We prefer, \b however, to use the memory representation as a private