# Copyright (c) 2012 David Munger, Pierre L'Ecuyer, Université de Montréal.
# 
# This file is part of Lattice Builder.
# 
# Lattice Builder 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 3 of the License, or
# (at your option) any later version.
# 
# Lattice Builder is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Lattice Builder.  If not, see <http://www.gnu.org/licenses/>.

/*! \page impl Implementation Notes

\section impl_func_args Function Arguments

In Lattice Builder, there are three different types of declarations of function
arguments:
\code
void f(const T& x) // if f only reads x
void f(T& x)       // if f writes to x
void f(T x)        // if f needs a copy of x
\endcode
Although the first prototype allows \c f to make a copy of \c x internally, it
is best to leave it to the compiler to do it.  For example, the following code
will cause two instantiations of objects of type \c T:
\code
void f(const T& x) { T y = x; y.modify(); }
...
f(T());
\endcode
whereas the following allows the compiler to instantiate only one object of type
\c T:
\code
void f(T y) { y.modify(); }
...
f(T());
\endcode

\section impl_seq Sequence

In multiple situations, Lattice Builder needs to access arrays of values that
can interchangeably be computed on-the-fly or pre-computed.  The concept of
<em>sequence</em>, in the sense of ordered list rather than infinite
mathematical sequence, provides in Lattice Builder a unified interface for both.
The elements of a sequence are accessed via immutable iterators (\c
const_iterator) with the standard syntax as used for the standard C++
containers, as in the following example:
\code
MySeq seq; // must implement begin() and end()
for (MySeq::const_iterator it = seq.begin(); it != seq.end(); ++it)
   std::cout << *it << std::endl;
\endcode
Or, using the new C++11 \c auto keyword and \c for syntax:
\code
MySeq seq; // must implement begin() and end()
for (const auto& elem : seq)
   std::cout << elem << std::endl;
\endcode
Concrete examples are given in the tutorial in sections \ref libtut_genseq,
\ref libtut_latseq and \ref libtut_meritseq .

\sa
   LatBuilder::GenSeq
   LatBuilder::GenSeqSeq
   LatBuilder::LatSeq
   LatBuilder::MeritSeq

\remark
   The LatBuilder::TextStream namespace provides streaming operators to
   iterate over sequences with a more compact syntax:
   \code
   using TextStream::operator<<;
   MySeq seq; // must implement begin() and end()
   std::cout << seq << std::endl;
   \endcode
   Concrete examples are given in the tutorial in section \ref libtut_textstream .


\section impl_bridgeseq Bridge Sequence

The values in a sequence often need to be mapped to other values, possibly of a
different type.  For that purpose, Lattice Builder introduces the concept of a
<em>bridge sequence</em>, which contains the mapped elements in the same order
as the sequence it is based on.

\sa LatBuilder::BridgeSeq


\section impl_polymorphism Static Polymorphism

Traditional object-oriented programming makes use of dynamic polymorphism, where
the exact class of an object is resolved at execution time, dynamically.  It
follows that polymorphic member function calls cannot be inlined, so it is often
not advisable to place such a call in the core of a loop with many iterations,
at the risk of cumulating inderections due to both polymorphism and function
calls.

Some algorithms implemented by Lattice Builder come in several variants which
require either polymorphic function calls inside such loops or a large amount
of duplicated code with tiny differences.  C++ allows to circumvent that
problem through the use of <em>static polymorphism</em>, which enables
compile-time resolution of the types together with member function inlining.

In some places, static polymorphism is used regardless that dynamic
polymorphism could have been used without any notable performance loss, in
order to maintain a consistent design.  We prefer making common usage
patterns of Lattice Builder's classes easier to recognize, even if that means
a little bit more verbose code in places.

The most obvious example is the case of sequence classes.  Their member
functions \c begin()  and \c end() return iterators; the type of an iterator
is often specific to the type of the sequence it is pointing to.

Another example is the size parameter is represented by a different class
depending on
whether ordinary or embedded lattices are considered.  In both cases, the class
implements a \c numPoints() member function, that returns the number of points
in the lattice, and that is accessed frequently in some parts of the code.  In a
traditional object-oriented approach, the two classes would derive from the same
abstract base class, and would have required runtime object-type resolution at
the call points of \c numPoints().  With the static polymorphism approach, the
\c numPoints() function can be efficiently inlined by the compiler, thus
avoiding both the overhead due to the function call and to runtime object-type
resolution.



\section impl_concepts Concept

Concepts in C++ can be thought of as the static-polymorphism counterpart of
dynamic-polymorphism interfaces.  Like interfaces, concepts can specify
requirements on the members of a class; unlike interfaces, the data types of the
arguments and of the return value of a member function can differ across classes
implementing the same concept.  Furthermore, a concept can require type
definitions (typedefs or nested classes) inside of a class.
A well-known example of concept it that of \c iterator or of \c const_iterator
from the STL.

Although requirements on the types are not explicited with concepts
definitions in Lattice Builder, but the code is built around the
idiom of concepts.

By convention in Lattice Builder, classes representing the same concept are
regrouped in the same namespace.

The most important concepts are described by means of example in the \ref
libtut.



\section impl_memory Memory Management

In Lattice Builder, when a non-trivial object is no longer needed in its scope
after it is passed as an argument to a constructor or factory function, it is
generally std::move()'d to the constructor or function in question.
The compiler takes care of using the default move constructor on the object
that is passed to the constructor and thus avoids copying the object, which can
safely be stored as a class member of the `owner' object.
Generator sequences (see the GenSeq namespace) are an example of non-trivial
objects that are transferred to other  ̀owner' objects using this mechanism.
Weights objects, such as instances of LatCommon::ProductWeights or of
LatCommon::ProjectionDependentWeights, are other examples of non-trivial
objects, but because they are polymorphic, they are stored using a
std::unique_ptr, which in turn, is passed using either std::move() or,
equivalently, std::unique_ptr::release().
There are a few exceptions to that ownership policy, notably figures of merit
like instances of WeightedFigureOfMerit or of CoordUniformFigureOfMerit.
Some classes store references to such objects, so the objects themselves are
also stored using std::unique_ptr so that references remain valid even after
the object ownership has changed.



\section impl_cpp11 Usage of the C++11 Standard

Lattice Builder makes uses of the following C++11 features:
- auto-typed variables
- range-based for-loop
- std::function and std::bind
- rvalue references
- move constructors and assignment operators
- static assertions
- extern templates
- null pointer constant
- strongly typed enums
- initializer lists
- non-static data member initializers
- template aliases



\section impl_boost Usage of the Boost C++ Libraries

The Lattice Builder library depends on the following
<a href="http://www.boost.org/">Boost libraries</a>:
<ul>
	<li><a href="http://www.boost.org/doc/libs/release/libs/math/doc/html/index.html">Math</a></li>
	<li><a href="http://www.boost.org/doc/libs/release/libs/numeric/ublas/doc/index.htm">uBLAS</a></li>
	<li><a href="http://www.boost.org/doc/libs/release/libs/iterator/doc/index.html">Iterator</a></li>
	<li><a href="http://www.boost.org/doc/libs/release/libs/accumulators/">Accumulators</a></li>
	<li><a href="http://www.boost.org/doc/libs/release/libs/signals2/">Signals2</a></li>
	<li><a href="http://www.boost.org/doc/libs/release/libs/tokenizer/index.html">Tokenizer</a></li>
	<li><a href="http://www.boost.org/doc/libs/release/libs/conversion/lexical_cast.htm">Lexical Cast</a></li>
</ul>

In addition to these, the Lattice Builder command-line tool also depends on the
following
<a href="http://www.boost.org/">Boost libraries</a>:
<ul>
	<li><a href="http://www.boost.org/doc/libs/release/doc/html/program_options.html">Program Options</a></li>
</ul>

Only the Program Options library requires building and linking; the
others are header-only libraries.



\section impl_fftw Usage of FFTW

The fast CBC implementation of Lattice Builder, as well as the computation of
the \f$R_\alpha\f$ criterion, depends on the
<a href="http://www.fftw.org/">FFTW library</a>.

*/
vim: ft=doxygen spelllang=en spell
