README 28.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
/*! \file README
 * \brief C++ container library general documentation
 *
 * ----------------------------------------------------------------------------
 *
 * $Id: README,v 1.1 2002-12-06 19:08:18 forbrig Exp $
 * 
 * Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt) 
 * 
 * C++ container library general documentation
 *
 * This file contains:
 *  - documentation of namespace contxx
 *  - mainpage text
 *  - documentation for pages:
 *    - \ref page_naming
 *    - \ref page_general
 *    - \ref page_using
 *    - \ref page_notes
 * 
 * REVISIONS and CHANGES 
 *  - 27/04/2002   V1.0   Thomas Forbriger
 *  - 21/11/2002   V1.1   entirely reworked
 *  - 21/11/2002   V1.2   added user manual information
 * 
 * ============================================================================
 */

/*! \brief Root namespace of library
  
  This namespace contains all modules of the library
  (see \ref sec_main_modules).
  While contxx::Array is the only compound in this namespace, all others are
  placed in sub namespaces.
  When working with the binary version of the library, you have to use
  contxx::prebuilt in place of contxx (see \ref sec_main_binary).
 */
namespace contxx {
} // namespace contxx

/*======================================================================*/

/*! \mainpage

\author Thomas Forbriger
\since May 2002
\date November 2002
\version V1.0
$Id: README,v 1.1 2002-12-06 19:08:18 forbrig Exp $

\section main_aims Aims of the 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.

  Contents of this page:
  - \ref sec_main_modules
    - \ref sec_main_modules_array 
    - \ref sec_main_modules_subscriptor
    - \ref sec_main_modules_shape
    - \ref sec_main_modules_representation
    - \ref sec_main_modules_shaper
    - \ref sec_main_modules_iterator
  - \ref sec_main_helpers
    - \ref sec_main_helpers_tuple
    - \ref sec_main_helpers_types
    - \ref sec_main_helpers_range
    - \ref sec_main_helpers_other
  - \ref sec_main_namespaces
  - \ref sec_main_constness 
  - \ref sec_main_binary 

  Additional information:
  - \ref page_using 
    - \ref sec_using_constructor
    - \ref sec_using_include
  - \ref page_representation
    - \ref sec_representation_types
    - \ref sec_representation_const
  - \ref page_shapes_and_subscriptors
  - \ref page_naming 
    - \ref sec_nameing_identifiers
    - \ref sec_nameing_files
  - \ref page_general
    - \ref sec_arrays_decisions
    - \ref sec_arrays_represented
    - \ref sec_arrays_interfaced
    - \ref sec_arrays_const
    - \ref sec_arrays_questions

\section sec_main_modules Modules of the library

  The main container class provided by the library is contxx::Array. It
  inherits from a Subscriptor class, which again inherits from a Shape and a
  Representation class (see inheritance diagram for contxx::Array).
  The roles of these classes are:
  - contxx::Array: The user interface 
    (see \ref sec_main_modules_array).
  - Subscriptor: Provides bracket-operator, i.e. 
    multidimensional index operator
    (see \ref sec_main_modules_subscriptor).
  - Shape: Defines the storage layout and index ranges
    (see \ref sec_main_modules_shape).
  - Representation: Provides the actual storage in memory
    (see \ref sec_main_modules_representation).

  \sa \ref page_shapes_and_subscriptors
  \sa \ref page_representation

  \todo
    In the near future the library has to provide projection operator
        classes to select subsets of the data.

  \todo
    A future version of the library has to provide iterators for sequential
        access.

\subsection sec_main_modules_array Module Array

  The array class inherits from a subscriptor. 
  There is only one array class template (contxx::Array presented in array.h).
  Its functionality is selected through the template arguments Subscriptor and
  Representation. The array class template is declared in the main namspace
  contxx.

\subsection sec_main_modules_subscriptor Module Subscriptor

  Subscriptors are also called "shaped representations". They combine the
  functionality of representations and shapes on a raw level. They just add
  multi-dimensional access operators, with multi-index argument lists.
  They are collected in the namespace contxx::subscriptor.
  You have to pass a Subscriptor template parameter to contxx::Array. This
  template parameters selects a Subscriptor and a Shape (since both are
  closely related)

  Provided subscriptors are:
  -# contxx::subscriptor::StridedRepresentation 
     (for contxx::shape::Strided shaped arrays)
     is presented in shape/strided_repr.h
  -# contxx::subscriptor::DenseStridedRepresentation
     (for contxx::shape::DenseStrided shaped arrays)
     is presented in shape/densestrided_repr.h

  \sa \ref page_shapes_and_subscriptors

\subsection sec_main_modules_shape Shapes

  Shapes define the index mapping from a multi-dimensional domain to the
  linear domain of memory storage (as provided through %representations).
  It also defines index ranges applicable to the array.
  A Shape class for the array is selected indirectly through the Subscriptor
  template parameter (see \ref sec_main_modules_subscriptor)

  contxx::shape::Strided provides the common rectangular array layout. A
  variant contxx::shape::DenseStrided will provide the %shape of a dense
  memory layout (with stride(0)=1). All shape classes are collected in the
  namespace contxx::shape.

  Provided shapes are:
  -# contxx::shape::Strided
     (rectangular layout)
     presented in shape/strided.h
  -# contxx::shape::DenseStrided
     (rectangular but addressing the memory continuously)
     presented in shape/densestrided.h

  Additional shapes may be defined for packed array layouts (e.g. for
  band-matrices, upper triangular matrices, etc.) in future versions of the
  library.

  \sa \ref page_shapes_and_subscriptors

\subsection sec_main_modules_representation Memory Representations

  Memory Representations are means to access a block of memory. The
  %representation classes provide automatic memory allocation control.
  The Representation is selected through a template parameter passed to
  contxx::Arrays.
  The
  standard %representation is contxx::representation::SharedHeap, which
  provides reference semantics, i.e. it performs shallow copies. The classes
  implementing different concepts of memory representations are collected in
  namespace contxx::representation.

  Provided representations are:
  -# contxx::representation::SharedHeap 
      (heap allocation, reference counting and shallow copy)
      presented in repr/sharedheap.h
  -# contxx::representation::NormalHeap 
      (heap allocation and deep copy)
      presented in repr/normalheap.h
  -# contxx::representation::Global 
      (access to external global data, shallow copies)
      presented in repr/global.h
  -# contxx::representation::Rigid 
      (fixed size, stack data, deep copy)
      presented in repr/rigid.h

  \sa \ref page_representation
  \sa \ref sec_representation_types

\subsection sec_main_modules_shaper Shapers

  When constructing an array you have to define its layout.
  Normally you will not like to deal with index range arrays and internals of
  the Shape base class.
  Shapers offer a compact means to define an array's shape.
  If you want e.g. define an array \c A of ints with Fortran layout, three
  dimensions and the index ranges [-2:2], [1:4], and [6:10] you have to code
  \code
  contxx::Array<int, 3> A(contxx::shaper::Fortran<3>(-2,2)(4)(6,10));
  \endcode
  Shapers are presented in namespace contxx::shaper.

  Provided shapers are:
  -# contxx::shaper::Fortran
     (presented in contxx/shaper/fortran.h

  \sa \ref Shaper

\subsection sec_main_modules_iterator Iterators

  Iterators provide sequential access to the elements of an array. This is
  most convenient for copying, input/output operations and scalar operations.
  Iterators in that way hide the dimensionality of the corresponding array and
  thus are most useful together with multi-dimensional arrays.

/*----------------------------------------------------------------------*/

\section sec_main_helpers Library utilities
  There exists some code that is not directly part of the main modules, but
  supports their use.

\subsection sec_main_helpers_tuple contxx::shape::tuple
  You have to pass arguments of type contxx::util::SimpleRigidArray to the
  constructors of contxx::Array.
  Use contxx::shape::tuple (collected in contxx::shape and presented in
  shape/shaper.h) to create them conveniently.
  \sa \ref sec_general_dimension
  \sa \ref anchor_simplerigigarray "discussion at SimpleRigidArray"
  \sa tests/arraytest.cc

\subsection sec_main_helpers_types Types
  Explicit types used within the library base on typedefs presented in
  util/types.h
  This allows us to change the type of a subscript index (e.g.) if needed on
  future architecture.
  The following typedefs are collected in namespace contxx::util:

    -# contxx::util::Tdim
    -# contxx::util::Tsize
    -# contxx::util::Tsubscript

  Use the using directive if you want to access them conveniently
  (see \ref sec_main_namespaces).
  
\subsection sec_main_helpers_range contxx::shape::range
  The index ranges are handled within the Shape category module by menas of a
  range class.
  This class is presented in shape/range.h and may be found in namespace
  contxx::shape.
  The range class is in particular usefull to find the smallest index range
  matching several ranges given or the total index range spanned by some
  subranges.

\subsection sec_main_helpers_other Others
  -# contxx::util::SimpleRigidArray is a convenient means to pass a small
     set of values.
     It is presented in util/simplearray.h and namespace contxx::util
  -# contxx::util::Inline and its associated functions is a means to
     conveniently inline operations on raw arrays.
     It is presented in util/rawarfun.h and namespace contxx::util
  -# contxx::util::Qualified is a traits-like class needed to provide
     conversion operators to arrays of const elements.
     It is presented in util/qualified.h and namespace contxx::util

/*----------------------------------------------------------------------*/

\section sec_main_namespaces Namespaces

  We make excessive use of namespaces. This my seem inconvenient at a first
  glance. Use statements like

  \code
  using namespace contxx::representations;
  \endcode

  or 

  \code
  using contxx::util::SimpleRigidArray;
  \endcode

  for convenient access.

/*----------------------------------------------------------------------*/

\section sec_main_constness Const correctness

  Since the standard %representation contxx::representation::SharedHeap has
  reference semantics, we have to distinguish between the const-ness of the
  container (its shape, the memory it refers to, etc.) and the contained
  elements. 

  - const-ness of the container: is achived by declaring the container
    instance with the qualifier \c const.
  - const-ness of the elements: is achieved by using a container for an
    element type with qualifier \c const.

  Convenient operators for conversion from containers of elements with type \c
  T to containers of elements with type \c const \c T are provided.

  \sa \ref sec_representation_const

/*----------------------------------------------------------------------*/

\section sec_main_binary Binary library

  We provide a binary version of the library. It contains a set of prebuilt
  class objects. Using this version and linking against the binary library
  libcontxx.a should reducde compilation times in comparison to complete
  template evaluation.
  This will become more significant the more code is factored out to separate
  definition headers.
  This approach offers no improvement with inlined code (which we use
  extensively in array access functions).

  To use the binary version you should include binarry.h in place of array.h
  You will find all modules in contxx::prebuilt that are in contxx in the
  full-template version.

  \sa tests/binarraytest.cc
  \sa binarray.h

*/

/*======================================================================*/

/*! \page page_naming Naming conventions

\section sec_nameing_identifiers Classes, Typedefs, etc.

  During coding it is sometimes helpfull to recognize the meaning of an
  identifier due to some signals in irs name. Therefor the following
  guidelines are used. The nameing of template parameters is left free for
  convenience.

  \par Classes
   
  Class names always start with a capital letter.

  \par Typedefs

  Typedefs always start with a capital \c T.

  \par Member data

  Member data identifiers always start with a capital \c M.

\section sec_nameing_files Filenames

  Files with the extension \c .cc contain only non-template definitions. Files
  with the extension \c .h may contain prototypes, class declarations or
  template code. Files ending on \c def.h contain template code definitions
  that is factored out to be compilable into a binary library for explicit
  instantiation.

*/

/*======================================================================*/

/*! \page page_general General notes

This page contains some brainstorming collected during the design and
construction phase.

\section sec_arrays_decisions Design Desicions
\subsection sec_general_dimension Template defined dimensionality
  We make excessive use of template code.
  This includes that we define the dimensionality of arrays by a template
  parameter.
  In most cases this works just fine.
  However for some of the jobs we have to define different functions for
  arrays of different dimensionality.
  Examples are the construction of the arrays, where we want to pass explicit
  index ranges for each dimension and the index (bracket) operators where we
  need one index per dimension.
  The quick-and-dirty approach is to provide constructors and index operators
  for every dimensionality supported by the library.
  However this doesn't work for precompiled template code 
  (see \ref sec_main_binary).
  In the case of explicit instantiation every part of the class definition
  must be compilable for the given set of template parameters. 
  But the index operator with five arguments will not compile for arrays with
  three dimensions.
  I tackle this problem in three different ways:

  \par 1. The constructors used with classes from the Shaper category
  A Shaper class offers a very compact notation to create an arrays shape and
  pass it to the constructor of contxx:Array.

  \sa \ref Shaper
  \sa \ref sec_main_modules_shaper
  \sa contxx::shaper
  \sa contxx::shaper::Fortran
  \sa tests/arraytest.cc

  \par 2. The constructors used with tuple-functions
  The array constructors take a contxx::util::SimpleRigidArray of appropriate
  size. For an array with three dimensions we must pass a SimpleRigidArray
  with three elements. Since the size of SimpleRigidArray is defined by a
  template parameter it just fits well in the template code.
  However this just migrates the problem from the contxx::Array constructors
  to the contxx::util::SimpleRigidArray constructors.
  The problem is solved finally through a set of helper functions with an
  overloaded version for each dimensionality.
  The are called contxx::shape::tuple and are just used to create objects of
  type contxx::util::SimpleRigidArray.
  They are a kind of external constructors with an appropriate number of
  arguments.
  If you need a SimpleRidigArray<int,3> initialized with {3,8,2}, just code
  the construct
  \code
  contxx::shape::tuple(int(3),8,2)
  \endcode
  This function returns exactly the SimpleRigidArray object you need.
  See the \ref anchor_simplerigigarray "discussion" in the documentation of
  contxx::util::SimpleRigidArray

  \deprecated
  The approach to construct arrays by means of passing index ranges directly
  is deprecated.
  It highly depends on the internal structure of the used Shape.
  Since there may be future Shape classes to which rectangular index ranges
  make no sense, we prefer to construct arrays be means of Shaper classes.
  The contxx::Array constructors that take index-array arguments will be
  removed in the future!

  \par 3. Index operators
  The first approach with SimpleRigidArray is not appropriate for index
  operators.
  Index operators are typically used in the innermost loop of code. 
  A bad performance of index operators is a severe penalty for the whole
  program.
  The approach with SimpleRigidArray involves the creation of temporary
  objects.
  This cannot be tolerated in index access to array elements.

  \par
  The approach we use for index operators involves a Subscriptor base class
  category.
  Subscriptors are just used to factor out the multidimensional index
  operators from the other modules.
  Thus we may provide a specialization for each dimensionality with not too
  much code overhead.
  See the discussion \ref page_shapes_and_subscriptors

\subsection sec_arrays_represented Represented memory
  The arrays are implemented as interfaces to represented memory. They are
  interfaces to a set of different memory representations. This allows us to
  use the same array class templates for totally different purposes with
  different needs of memory access and execution efficiency. All arrays
  guarantee to
    -# allocate memory only through their specific representation
    -# perform a shallow (full array) copy (be copy constructor or copy
       operator) only by copying the representation
    -# access their elements through their representation
  Elementwise (deep) copy must be requested if you want to ensure this type of
  copy. However, there are representations that do a deep copy in any case.

  Although the element access has always to be done through the
  representation, this may be implemented fairly efficient by inlined member
  functions.

\subsection sec_arrays_interfaced Concrete and interfaced arrays
  All standard array interfaces are templates. The element type, the type of
  memory representation and the subscription type are selected through
  template parameters. Thus dense onedimensional arrays are of a different
  type than any other onedimensional memory subscription. Shared heap for
  integers are of a different type then a stack array of integers, although
  the same interface and functionality is used for element access. No virtual
  function are involved in that concept. 

  In some rare cases it may be usefull to have a standard interface class to
  (say) 1D-arrays. This may be achieved by an abstract base class defining the
  interface and a set of different implementations that inherit from this base
  and fill the user-must-define functions. For this the pure templates may be
  used to implement the functionality.

  However, this concept involves virtual functions. And since the main job of
  an array class is element acces, the virtual function call overhead will be
  present for each element access. This might be not desireable. 

\subsection sec_arrays_const Constness of arrays
  \deprecated
  This discussion of a solution of const correctness is out-dated! Please refer
  to \ref sec_main_constness and \ref sec_representation_const for a recent
  approach. 
  The solution discussed below is based on the usual textbook approach which
  is to define a second class which allows no change of elements.
  \b The \b library \b chooses \b a \b different \b solution:
  We simply use the same class definition as for non-const value and define
  them for a const element type.
  The classes provide conversion operators from arrays of element type \c T to
  arrays of element type \c const \c T.
  This approach is so direct, elegant and easy to implement, that it remains a
  mystery, why it doesn't appear in textbooks.
  
  The array classes and classes derived from them (e.g. series classes) are
  desingned to implement handle semantics through using
  tf_generic::TSharedHeap. Their use follows reference semantics. Passing
  an instance together with a \c const qualifier just means that the array
  instance itself may not be changed in a function. I.e. it may not be filled
  with another heap reference or another projection. However a local copy of
  the heap reference may be created. Thus the array values may be changed by a
  function that promises const-ness to its arguments. For this reason we
  provide also \c const versions of the array classes. They provide no
  mechanism to manipulate array contents or to creat non-const local copies.

  A declaration 
  \code
  const ArrayType array;
  \endcode
  means: The array instance (the container) is const. I.e.
  its reference to the heap may not be changed, its projection may not be
  changed. However, its elements (the contained data) \b may \b be \b changed!

  A declaration 
  \code 
  ConstArrayType array;
  \endcode
  means: The instance is designed to forbid any
  changes of the array elements (the contained data).
  Local copies are only allowed to types that
  forbid array element manipulation too. However, without \c const qualifier
  an instance (container) of type \c ConstArrayT may be changed. I.e. a new
  reference to heap or a new projection may be assigned to it.

  The element access functions declared \c const normally do not allow array
  element manipulation. Thus also a \c const \c ArrayT follows the typical
  meaning of const-ness in this regard. However, it may not promise full
  const-ness, since a local, non-const copy may be created.
  The latter might be prohobited by the full access array classes, if they
  do not promise const-ness of the argument of the copy constructor or the
  copy operator. However, in that case it would not be possible to pass arrays
  as return values. Why? The return value of a function is an R-value (in case
  you do not return a reference). It must be used in the sense of a variable
  declared \c const. Returning from a function involves creating copies. When
  the compiler allows only for const-ness of the copy argument, it
  automatically performs a type conversion to the \c ConstArrayType base
  class. Thus we would always receiver \c ConstArrayType arrays from functions
  --- which we do not want.

  \sa tf_array::TDenseShiftedArray1D

\subsection sec_arrays_questions Questions and Answers
\par Why do we define all these array types ourselves? 
  Standard array packages
  and libraries also contain various array representations with array
  projections. But, what we want to implement mainly is a set of arrays and
  projections with handle semnatics. There is only one heap location where
  the actual array values are stored. We may have a lot of array projections
  using this heap area. They do memory control through a handle mechanism.
  Thus the heap is allocted as long as any of the projections exists. The
  last projection frees the heap in its destructor. This mechanism \b must be
  done inside the arrays and projections. It cannot be done with outside
  handle classes.

\par Why don't we use a standard matrix package?
  There is no real "standard" matrix package up to now. There are several
  different matrix packages all with different design ideas. Common to all of
  them is, that they allow array handles only in the sense of array handles.
  That means, that you allways have a handle that contains an array. This
  makes the use of them more obscure and complicated. Since the possibility to
  allow structured access to the same data with shallow copy and projections
  to subsets of the data, was a main reason to use C++, I decided to start my
  own array module. Cooperation with existing code (like LAPACK) is always
  possible, if we also provide appropriate interfaces to the memory that holds
  the array contents.

\par Why don't we use the STL vector valarray classes?
  The Standard Template Library (STL) offers a rich, powerful and well tested
  set of containers. However, they are all one-dimensional. So this would have
  saved us only the work for the 1D-classes. The \c valarray containers offer
  also multi-dimensional access through slices. But the application of slices
  is rather complicated. They may not be representated by one object alone. It
  always needs the arrays together with a slice object. This may be ultimately
  efficient. But with our applications in mind, efficiency has to take place
  in the Fortran kernel of the code. Our array design is efficient enough and
  we emphasize easy-of-use instead.

\par Why don't we use the STL allocator concept?
  The STL allocator concept is similar to our 
  \ref sec_arrays_represented "representation"
  concept. It is designed to hide the actual task of memory allocation from
  the implementation of the containers. This may allow implementers to make
  memory allocation more efficients by providing system dependent allocators.
  However, the interaction between containers and allocators is rather
  complicated and was in a state of transition. It is not obvious to me that
  it could be possible to implement the concept of shared heap through the
  definition of an appropriate allocator allone. This would afford the
  containers to copy their content only by using the copy constructor and copy
  operator of the allocator and to access elements only through member
  functions of the allocator.

\par
  On the other hand, if there is a very powerful STL allocator available, it
  is still possible to implement a
  \ref sec_arrays_represented "memory representation"
  that uses an STL type allocator to retreive memory an thus may benefit from
  any high-performance memory management (like pooled memory). However, this
  is not the main aim of our module.

*/

/*======================================================================*/

/*! \page page_using HOWTO use this library
\section sec_using_constructor Constructing arrays
  Arrays are most easy constructed by means of a Shaper.
  If you want e.g. define an array \c A of ints with Fortran layout, three
  dimensions and the index ranges [-2:2], [1:4], and [6:10] you have to code
  \code
  contxx::Array<int, 3> A(contxx::shaper::Fortran<3>(-2,2)(4)(6,10));
  \endcode
  Shapers are presented in namespace contxx::shaper.

  \sa \ref Shaper
  \sa \ref sec_main_modules_shaper
  \sa contxx::shaper
  \sa contxx::shaper::Fortran
  \sa tests/arraytest.cc
  \sa \ref sec_general_dimension

\section sec_using_include Including header files
  The main set of \ref sec_main_modules "array modules" is included by
  contxx/array.h. This include the full templatized version of the library. We
  you want to take advantage of the 
  \ref sec_main_binary "precompiled binary library" you have to include
  contxx/binarray.h.
  This will set CONTXX_PREBUILT which places all definitions in
  contxx::prebuilt rather than just namespace contxx.
  Files like contxx/shaper/fortran.h or contxx/iterator.h are not included
  automatically by array.h or binarray.h.
  You have to include them separately.
  If you are using the precompiled library, you must include them \b after
  binarray.h so that they will place their declarations in contxx::prebuilt
  and take the declarations for other parts of the library from that namespace
  too.

  \par Mixing the pure template library and the binary version
  Mixing the pure template library and the binary version might not work with
  this version of the library. Once you included either array.h or binarray.h
  the include guards will prevent the precompiler from reading the files
  again. 
  This problem may be solved in a future version with a more elaborate include
  guard mechanism that takes account for CONTXX_PREBUILT.

*/

/*======================================================================*/

/* \page page_notes Programming notes
*/

// ----- END OF README -----