Commit 043c842a authored by edwin's avatar edwin
Browse files

First commit

parents
#undef mln_assertion
#undef mln_precondition
#undef mln_postcondition
#undef MLN_HAS_DEBUG
#include <cassert>
#ifndef MLN_NDEBUG
# define mln_assertion(expr) assert(expr)
# define MLN_HAS_DEBUG 1
#
#else
# define mln_assertion(expr) (void (0))
# define MLN_HAS_DEBUG 0
#endif
#define mln_precondition(expr) mln_assertion(expr)
#define mln_postcondition(expr) mln_assertion(expr)
#ifndef MLN_BOX_HH
# define MLN_BOX_HH
# include <mln/core/point.hpp>
# include <mln/core/iterator/fast_reverse_iterator.hpp>
namespace mln
{
// Fwd
template <typename T, unsigned dim> struct box_iter;
template <typename T, unsigned dim> struct box_rev_iter;
//
// \pre \tparam T must be an integral type
template <typename T, unsigned dim>
struct box
{
typedef typename point<T, dim>::type point_type;
typedef box_iter<T, dim> iterator;
typedef iterator const_iterator;
typedef mln::fast_reverse_iterator<iterator> reverse_iterator;
typedef reverse_iterator const_reverse_iterator;
bool has(const point_type& p) const
{
return (pmin <= p) && (p < pmax);
}
point_type shape() const
{
return pmax - pmin;
}
iterator begin() const
{
return iterator(*this, pmin);
}
iterator end() const
{
point_type pend = pmin;
pend[0] = pmax[0];
return iterator(*this, pend );
}
reverse_iterator rbegin() const
{
//point_type pend = pmax - (short)1;
return reverse_iterator(end());
}
reverse_iterator rend() const
{
//point_type pbeg = pmax - (short)1;
//pbeg[0] = pmin[0] - 1;
return reverse_iterator(begin());
}
#ifdef MLN_TBB
#endif
point_type pmin;
point_type pmax;
};
typedef box<short, 1> box1d;
typedef box<float, 1> box1df;
typedef box<short, 2> box2d;
typedef box<float, 2> box2df;
typedef box<short, 3> box3d;
template <typename T, unsigned dim>
inline
std::ostream&
operator<< (std::ostream& s, const box<T, dim>& b)
{
return s << "[" << b.pmin << " ... " << b.pmax << "]";
}
}
# include <mln/core/domain/box_iter.hpp>
#endif
#ifndef MLN_BOX_HH
# define MLN_BOX_HH
# include <mln/core/point.hpp>
namespace mln
{
// Fwd
template <typename T, unsigned dim> struct box_iter;
template <typename T, unsigned dim> struct box_rev_iter;
//
// \pre \tparam T must be an integral type
template <typename T, unsigned dim>
struct box
{
typedef typename point<T, dim>::type point_type;
typedef box_iter<T, dim> iterator;
typedef iterator const_iterator;
typedef box_rev_iter<T, dim> reverse_iterator;
typedef reverse_iterator const_reverse_iterator;
bool has(const point_type& p) const
{
return (pmin <= p) && (p < pmax);
}
point_type shape() const
{
return pmax - pmin;
}
iterator begin() const
{
return iterator(*this, pmin);
}
iterator end() const
{
point_type pend = pmin;
pend[0] = pmax[0];
return iterator(*this, pend );
}
reverse_iterator rbegin() const
{
point_type pend = pmax - (short)1;
return reverse_iterator(*this, pend);
}
reverse_iterator rend() const
{
point_type pbeg = pmax - (short)1;
pbeg[0] = pmin[0] - 1;
return reverse_iterator(*this, pbeg);
}
#ifdef MLN_TBB
#endif
point_type pmin;
point_type pmax;
};
typedef box<short, 1> box1d;
typedef box<float, 1> box1df;
typedef box<short, 2> box2d;
typedef box<float, 2> box2df;
typedef box<short, 3> box3d;
template <typename T, unsigned dim>
inline
std::ostream&
operator<< (std::ostream& s, const box<T, dim>& b)
{
return s << "[" << b.pmin << " ... " << b.pmax << "]";
}
}
# include <mln/core/domain/box_iter.hpp>
#endif
#ifndef MLN_CORE_BOX_ITER_H
# define MLN_CORE_BOX_ITER_H
# include <boost/iterator/iterator_facade.hpp>
# include <mln/core/iterator/fast_reverse_iterator.hpp>
# include <boost/iterator/reverse_iterator.hpp>
namespace mln
{
template <typename T, unsigned dim>
struct box_iter :
public boost::iterator_facade< box_iter<T, dim>, const typename box<T, dim>::point_type,
boost::bidirectional_traversal_tag, const typename box<T, dim>::point_type&>
{
typedef typename box<T, dim>::point_type point_type;
box_iter() {}
// box_iter(const box_rev_iter<T, dim>& it) :
// box_ (it.box_),
// point_ (it.point_)
// {
// }
box_iter(const box<T, dim>& box, point_type p) :
box_ (box),
point_ (p)
{
}
public:
friend class boost::iterator_core_access;
template <typename, unsigned> friend struct box_rev_iter;
inline
void increment()
{
for (int i = dim-1; ;--i)
{
point_[i] += 1;
if (point_[i] < box_.pmax[i] || i == 0)
break;
point_[i] = box_.pmin[i];
}
}
inline
void decrement()
{
for (int i = dim-1; ;--i)
{
point_[i] -= 1;
if (point_[i] >= box_.pmin[i] || i == 0)
break;
point_[i] = box_.pmax[i] - 1;
}
}
template <typename U>
bool equal(const box_iter<U, dim>& other) const
{
return this->point_ == other.point_;
}
const point_type& dereference() const
{
return point_;
}
box<short, dim> box_; // Domain iteration (do faster than reference)
point_type point_; // Site location
};
template <typename T, unsigned dim>
struct box_rev_iter :
public boost::iterator_facade< box_rev_iter<T, dim>, const typename box<T, dim>::point_type,
boost::bidirectional_traversal_tag, const typename box<T, dim>::point_type&>
{
typedef typename box<T, dim>::point_type point_type;
box_rev_iter() {}
box_rev_iter(const box_iter<T, dim>& it) :
box_ (it.box_),
point_ (it.point_)
{
}
box_rev_iter(const box<T, dim>& box, point_type p) :
box_ (box),
point_ (p)
{
}
public:
friend class boost::iterator_core_access;
template <typename, unsigned> friend struct box_iter;
inline
void decrement()
{
for (int i = dim-1; ;--i)
{
point_[i] += 1;
if (point_[i] < box_.pmax[i] || i == 0)
break;
point_[i] = box_.pmin[i];
}
}
inline
void increment()
{
for (int i = dim-1; ;--i)
{
point_[i] -= 1;
if (point_[i] >= box_.pmin[i] || i == 0)
break;
point_[i] = box_.pmax[i] - 1;
}
}
template <typename U>
bool equal(const box_rev_iter<U, dim>& other) const
{
return this->point_ == other.point_;
}
const point_type& dereference() const
{
return point_;
}
box<short, dim> box_; // Domain iteration (do faster than reference)
point_type point_; // Site location
};
}
// Specialization of the boost::reverse_iterator
// Because increment and decrement have constant complexity but quite
// expensive compared to stl iterator.
namespace boost
{
template <>
template <typename T, unsigned dim>
struct reverse_iterator< mln::box_iter<T, dim> > :
mln::fast_reverse_iterator< mln::box_iter<T, dim> >
{
private:
typedef mln::box_iter<T, dim> base_it;
typedef mln::fast_reverse_iterator<base_it> base;
public:
reverse_iterator() = default;
reverse_iterator(const reverse_iterator&) = default;
reverse_iterator(const base_it& it) : base(it) {}
};
// template <>
// template <typename T, unsigned dim>
// struct reverse_iterator< mln::box_rev_iter<T, dim> > : mln::box_iter<T, dim>
// {
// private:
// typedef mln::box_iter<T, dim> base;
// public:
// reverse_iterator() = default;
// reverse_iterator(const reverse_iterator&) = default;
// reverse_iterator(mln::box_rev_iter<T, dim> it) : base(--it) {}
// };
}
#endif // !MLN_CORE_BOX_ITER_H
#ifndef MLN_CORE_BOX_ITER_H
# define MLN_CORE_BOX_ITER_H
# include <boost/iterator/iterator_facade.hpp>
# include <boost/iterator/reverse_iterator.hpp>
namespace mln
{
template <typename T, unsigned dim>
struct box_iter :
public boost::iterator_facade< box_iter<T, dim>, const typename box<T, dim>::point_type,
boost::bidirectional_traversal_tag, const typename box<T, dim>::point_type&>
{
typedef typename box<T, dim>::point_type point_type;
box_iter() {}
// box_iter(const box_rev_iter<T, dim>& it) :
// box_ (it.box_),
// point_ (it.point_)
// {
// }
box_iter(const box<T, dim>& box, point_type p) :
box_ (box),
point_ (p)
{
}
public:
friend class boost::iterator_core_access;
template <typename, unsigned> friend struct box_rev_iter;
inline
void increment()
{
for (int i = dim-1; ;--i)
{
point_[i] += 1;
if (point_[i] < box_.pmax[i] || i == 0)
break;
point_[i] = box_.pmin[i];
}
}
inline
void decrement()
{
for (int i = dim-1; ;--i)
{
point_[i] -= 1;
if (point_[i] >= box_.pmin[i] || i == 0)
break;
point_[i] = box_.pmax[i] - 1;
}
}
template <typename U>
bool equal(const box_iter<U, dim>& other) const
{
return this->point_ == other.point_;
}
const point_type& dereference() const
{
return point_;
}
box<short, dim> box_; // Domain iteration
point_type point_; // Site location
};
template <typename T, unsigned dim>
struct box_rev_iter :
public boost::iterator_facade< box_rev_iter<T, dim>, const typename box<T, dim>::point_type,
boost::bidirectional_traversal_tag, const typename box<T, dim>::point_type&>
{
typedef typename box<T, dim>::point_type point_type;
box_rev_iter() {}
box_rev_iter(const box_iter<T, dim>& it) :
box_ (it.box_),
point_ (it.point_)
{
}
box_rev_iter(const box<T, dim>& box, point_type p) :
box_ (box),
point_ (p)
{
}
public:
friend class boost::iterator_core_access;
template <typename, unsigned> friend struct box_iter;
inline
void decrement()
{
for (int i = dim-1; ;--i)
{
point_[i] += 1;
if (point_[i] < box_.pmax[i] || i == 0)
break;
point_[i] = box_.pmin[i];
}
}
inline
void increment()
{
for (int i = dim-1; ;--i)
{
point_[i] -= 1;
if (point_[i] >= box_.pmin[i] || i == 0)
break;
point_[i] = box_.pmax[i] - 1;
}
}
template <typename U>
bool equal(const box_rev_iter<U, dim>& other) const
{
return this->point_ == other.point_;
}
const point_type& dereference() const
{
return point_;
}
box<short, dim> box_; // Domain iteration
point_type point_; // Site location
};
}
// Specialization of the boost::reverse_iterator
// Because increment and decrement have constant complexity but quite
// expensive compared to stl iterator.
namespace boost
{
template <>
template <typename T, unsigned dim>
struct reverse_iterator< mln::box_iter<T, dim> > :
mln::fast_reverse_iterator< mln::box_iter<T, dim> >
{
private:
typedef mln::box_iter<T, dim> base_it;
typedef mln::fast_reverse_iterator<base_it> base;
public:
reverse_iterator() = default;
reverse_iterator(const reverse_iterator&) = default;
reverse_iterator(base_it it) : base(it) {}
};
// template <>
// template <typename T, unsigned dim>
// struct reverse_iterator< mln::box_rev_iter<T, dim> > : mln::box_iter<T, dim>
// {
// private:
// typedef mln::box_iter<T, dim> base;
// public:
// reverse_iterator() = default;
// reverse_iterator(const reverse_iterator&) = default;
// reverse_iterator(mln::box_rev_iter<T, dim> it) : base(--it) {}
// };
};
#endif // !MLN_CORE_BOX_ITER_H
#ifndef MLN_CORE_DOMAINS_DTRANSFORMED_HPP
# define MLN_CORE_DOMAINS_DTRANSFORMED_HPP
# include <mln/core/range.hpp>
/// \file
/// \brief Lazy transformation of a domain through a function
namespace mln {
// FWD
namespace internal {
template <typename Domain, typename Function, typename domain_category>
struct internal::domain_transform;
}
/**
* \brief Lazy application of the function to site domain
*
* \param domain The domain to be mapped.
* \param f The function to map.
*
* \post The following sementic is hold:
* \code
* for (x,y: zip(domain, dtransform(domain, f))
* mln_invariant(y == f(x))
* \endcode
**/
template <typename Domain, typename Function>
internal::domain_transform<Domain, Function, typename range_category<Domain>::type>
dtransform(const Domain& domain, Function f);
//******************
// Implementation *
//******************
namespace internal
{
template <typename Domain, typename Function>
struct domain_transform<Domain, Function, single_pass_range_tag>
{
typedef single_pass_range_tag category;
typedef boost::range_value<Domain>::type value_type;
typedef boost::range_iterator<Domain>::type base_iterator_;
typedef boost::transform_iterator<Function, base_iterator_> iterator;
typedef iterator const_iterator;
domain_transform(const Domain& d, Function f):
domain_ (d), f_ (f)
{}
iterator begin() const { return iterator(domain.begin(), f_); }
iterator end() const { return iterator(domain.end(), f_); }
protected:
D domain_;
Function f_;
};
template <typename Domain, typename Function>
struct domain_transform<Domain, Function, forward_range_tag>
: domain_transform<Domain, Function, single_pass_range_tag>
{
typedef domain_transform<Domain, Function, single_pass_range_tag> base;
domain_transform(const Domain& d, Function f): base(d, f) {}
}
template <typename Domain, typename Function>
struct domain_transform<Domain, Function, bidirectional_tag>