Forked from
gmsh / gmsh
16076 commits behind the upstream repository.
-
Jean-François Remacle authoredJean-François Remacle authored
gmm_ref.h 21.42 KiB
// -*- c++ -*- (enables emacs c++ mode)
//===========================================================================
//
// Copyright (C) 2000-2008 Yves Renard
//
// This file is a part of GETFEM++
//
// Getfem++ is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 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 MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// License for more details.
// You should have received a copy of the GNU Lesser 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.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
//
//===========================================================================
#ifndef GMM_REF_H__
#define GMM_REF_H__
/** @file gmm_ref.h
@author Yves Renard <Yves.Renard@insa-lyon.fr>
@date August 26, 2000.
* @brief Provide some simple pseudo-containers.
*
* WARNING : modifiying the container infirm the validity of references.
*/
#include <iterator>
#include "gmm_except.h"
namespace gmm {
/* ********************************************************************* */
/* Simple reference. */
/* ********************************************************************* */
template<typename ITER> class tab_ref {
protected :
ITER begin_, end_;
public :
typedef typename std::iterator_traits<ITER>::value_type value_type;
typedef typename std::iterator_traits<ITER>::pointer pointer;
typedef typename std::iterator_traits<ITER>::pointer const_pointer;
typedef typename std::iterator_traits<ITER>::reference reference;
typedef typename std::iterator_traits<ITER>::reference const_reference;
typedef typename std::iterator_traits<ITER>::difference_type
difference_type;
typedef ITER iterator;
typedef ITER const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef size_t size_type;
bool empty(void) const { return begin_ == end_; }
size_type size(void) const { return end_ - begin_; }
const iterator &begin(void) { return begin_; }
const const_iterator &begin(void) const { return begin_; }
const iterator &end(void) { return end_; }
const const_iterator &end(void) const { return end_; }
reverse_iterator rbegin(void) { return reverse_iterator(end()); }
const_reverse_iterator rbegin(void) const
{ return const_reverse_iterator(end()); }
reverse_iterator rend(void) { return reverse_iterator(begin()); }
const_reverse_iterator rend(void) const
{ return const_reverse_iterator(begin()); }
reference front(void) { return *begin(); }
const_reference front(void) const { return *begin(); }
reference back(void) { return *(--(end())); }
const_reference back(void) const { return *(--(end())); }
void pop_front(void) { ++begin_; }
const_reference operator [](size_type ii) const { return *(begin_ + ii);}
reference operator [](size_type ii) { return *(begin_ + ii); }
tab_ref(void) {}
tab_ref(const ITER &b, const ITER &e) : begin_(b), end_(e) {}
};
/* ********************************************************************* */
/* Reference with index. */
/* ********************************************************************* */
// template<typename ITER> struct tab_ref_index_iterator_
// : public dynamic_array<size_t>::const_iterator
// {
// typedef typename std::iterator_traits<ITER>::value_type value_type;
// typedef typename std::iterator_traits<ITER>::pointer pointer;
// typedef typename std::iterator_traits<ITER>::reference reference;
// typedef typename std::iterator_traits<ITER>::difference_type
// difference_type;
// typedef std::random_access_iterator_tag iterator_category;
// typedef size_t size_type;
// typedef dynamic_array<size_type>::const_iterator dnas_iterator_;
// typedef tab_ref_index_iterator_<ITER> iterator;
// ITER piter;
// iterator operator ++(int)
// { iterator tmp = *this; ++(*((dnas_iterator_ *)(this))); return tmp; }
// iterator operator --(int)
// { iterator tmp = *this; --(*((dnas_iterator_ *)(this))); return tmp; }
// iterator &operator ++()
// { ++(*((dnas_iterator_ *)(this))); return *this; }
// iterator &operator --()
// { --(*((dnas_iterator_ *)(this))); return *this; }
// iterator &operator +=(difference_type i)
// { (*((dnas_iterator_ *)(this))) += i; return *this; }
// iterator &operator -=(difference_type i)
// { (*((dnas_iterator_ *)(this))) -= i; return *this; }
// iterator operator +(difference_type i) const
// { iterator it = *this; return (it += i); }
// iterator operator -(difference_type i) const
// { iterator it = *this; return (it -= i); }
// difference_type operator -(const iterator &i) const
// { return *((dnas_iterator_ *)(this)) - *((dnas_iterator_ *)(&i)); }
// reference operator *() const
// { return *(piter + *((*((dnas_iterator_ *)(this))))); }
// reference operator [](int ii)
// { return *(piter + *((*((dnas_iterator_ *)(this+ii))))); }
// bool operator ==(const iterator &i) const
// {
// return ((piter) == ((i.piter))
// && *((dnas_iterator_ *)(this)) == *((*((dnas_iterator_ *)(this)))));
// }
// bool operator !=(const iterator &i) const
// { return !(i == *this); }
// bool operator < (const iterator &i) const
// {
// return ((piter) == ((i.piter))
// && *((dnas_iterator_ *)(this)) < *((*((dnas_iterator_ *)(this)))));
// }
// tab_ref_index_iterator_(void) {}
// tab_ref_index_iterator_(const ITER &iter, const dnas_iterator_ &dnas_iter)
// : dnas_iterator_(dnas_iter), piter(iter) {}
// };
// template<typename ITER> class tab_ref_index
// {
// public :
// typedef typename std::iterator_traits<ITER>::value_type value_type;
// typedef typename std::iterator_traits<ITER>::pointer pointer;
// typedef typename std::iterator_traits<ITER>::pointer const_pointer;
// typedef typename std::iterator_traits<ITER>::reference reference;
// typedef typename std::iterator_traits<ITER>::reference const_reference;
// typedef typename std::iterator_traits<ITER>::difference_type
// difference_type;
// typedef size_t size_type;
// typedef tab_ref_index_iterator_<ITER> iterator;
// typedef iterator const_iterator;
// typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// typedef std::reverse_iterator<iterator> reverse_iterator;
// protected :
// ITER begin_;
// dynamic_array<size_type> index_;
// public :
// bool empty(void) const { return index_.empty(); }
// size_type size(void) const { return index_.size(); }
// iterator begin(void) { return iterator(begin_, index_.begin()); }
// const_iterator begin(void) const
// { return iterator(begin_, index_.begin()); }
// iterator end(void) { return iterator(begin_, index_.end()); }
// const_iterator end(void) const { return iterator(begin_, index_.end()); }
// reverse_iterator rbegin(void) { return reverse_iterator(end()); }
// const_reverse_iterator rbegin(void) const
// { return const_reverse_iterator(end()); }
// reverse_iterator rend(void) { return reverse_iterator(begin()); }
// const_reverse_iterator rend(void) const
// { return const_reverse_iterator(begin()); }
// reference front(void) { return *(begin_ +index_[0]); }
// const_reference front(void) const { return *(begin_ +index_[0]); }
// reference back(void) { return *(--(end())); }
// const_reference back(void) const { return *(--(end())); }
// tab_ref_index(void) {}
// tab_ref_index(const ITER &b, const dynamic_array<size_type> &ind)
// { begin_ = b; index_ = ind; }
// // to be changed in a const_reference ?
// value_type operator [](size_type ii) const
// { return *(begin_ + index_[ii]);}
// reference operator [](size_type ii) { return *(begin_ + index_[ii]); }
// };
/// iterator over a gmm::tab_ref_index_ref<ITER,ITER_INDEX>
template<typename ITER, typename ITER_INDEX>
struct tab_ref_index_ref_iterator_
{
typedef typename std::iterator_traits<ITER>::value_type value_type;
typedef typename std::iterator_traits<ITER>::pointer pointer;
typedef typename std::iterator_traits<ITER>::reference reference;
typedef typename std::iterator_traits<ITER>::difference_type
difference_type;
typedef std::random_access_iterator_tag iterator_category;
typedef tab_ref_index_ref_iterator_<ITER, ITER_INDEX> iterator;
typedef size_t size_type;
ITER piter;
ITER_INDEX iter_index;
iterator operator ++(int)
{ iterator tmp = *this; ++iter_index; return tmp; }
iterator operator --(int)
{ iterator tmp = *this; --iter_index; return tmp; }
iterator &operator ++() { ++iter_index; return *this; }
iterator &operator --() { --iter_index; return *this; }
iterator &operator +=(difference_type i)
{ iter_index += i; return *this; }
iterator &operator -=(difference_type i)
{ iter_index -= i; return *this; }
iterator operator +(difference_type i) const
{ iterator it = *this; return (it += i); }
iterator operator -(difference_type i) const
{ iterator it = *this; return (it -= i); }
difference_type operator -(const iterator &i) const
{ return iter_index - i.iter_index; }
reference operator *() const
{ return *(piter + *iter_index); }
reference operator [](int ii) const
{ return *(piter + *(iter_index+ii)); }
bool operator ==(const iterator &i) const
{ return ((piter) == ((i.piter)) && iter_index == i.iter_index); }
bool operator !=(const iterator &i) const { return !(i == *this); }
bool operator < (const iterator &i) const
{ return ((piter) == ((i.piter)) && iter_index < i.iter_index); }
tab_ref_index_ref_iterator_(void) {}
tab_ref_index_ref_iterator_(const ITER &iter,
const ITER_INDEX &dnas_iter)
: piter(iter), iter_index(dnas_iter) {}
};
/**
convenience template function for quick obtention of a indexed iterator
without having to specify its (long) typename
*/
template<typename ITER, typename ITER_INDEX>
tab_ref_index_ref_iterator_<ITER,ITER_INDEX>
index_ref_iterator(ITER it, ITER_INDEX it_i) {
return tab_ref_index_ref_iterator_<ITER,ITER_INDEX>(it, it_i);
}
/** indexed array reference (given a container X, and a set of indexes I,
this class provides a pseudo-container Y such that
@code Y[i] = X[I[i]] @endcode
*/
template<typename ITER, typename ITER_INDEX> class tab_ref_index_ref {
public :
typedef std::iterator_traits<ITER> traits_type;
typedef typename traits_type::value_type value_type;
typedef typename traits_type::pointer pointer;
typedef typename traits_type::pointer const_pointer;
typedef typename traits_type::reference reference;
typedef typename traits_type::reference const_reference;
typedef typename traits_type::difference_type difference_type;
typedef size_t size_type;
typedef tab_ref_index_ref_iterator_<ITER, ITER_INDEX> iterator;
typedef iterator const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
protected :
ITER begin_;
ITER_INDEX index_begin_, index_end_;
public :
bool empty(void) const { return index_begin_ == index_end_; }
size_type size(void) const { return index_end_ - index_begin_; }
iterator begin(void) { return iterator(begin_, index_begin_); }
const_iterator begin(void) const
{ return iterator(begin_, index_begin_); }
iterator end(void) { return iterator(begin_, index_end_); }
const_iterator end(void) const { return iterator(begin_, index_end_); }
reverse_iterator rbegin(void) { return reverse_iterator(end()); }
const_reverse_iterator rbegin(void) const
{ return const_reverse_iterator(end()); }
reverse_iterator rend(void) { return reverse_iterator(begin()); }
const_reverse_iterator rend(void) const
{ return const_reverse_iterator(begin()); }
reference front(void) { return *(begin_ + *index_begin_); }
const_reference front(void) const { return *(begin_ + *index_begin_); }
reference back(void) { return *(--(end())); }
const_reference back(void) const { return *(--(end())); }
void pop_front(void) { ++index_begin_; }
tab_ref_index_ref(void) {}
tab_ref_index_ref(const ITER &b, const ITER_INDEX &bi,
const ITER_INDEX &ei)
: begin_(b), index_begin_(bi), index_end_(ei) {}
// to be changed in a const_reference ?
const_reference operator [](size_type ii) const
{ return *(begin_ + index_begin_[ii]);}
reference operator [](size_type ii)
{ return *(begin_ + index_begin_[ii]); }
};
/* ********************************************************************* */
/* Reference on regularly spaced elements. */
/* ********************************************************************* */
template<typename ITER> struct tab_ref_reg_spaced_iterator_ {
typedef typename std::iterator_traits<ITER>::value_type value_type;
typedef typename std::iterator_traits<ITER>::pointer pointer;
typedef typename std::iterator_traits<ITER>::reference reference;
typedef typename std::iterator_traits<ITER>::difference_type
difference_type;
typedef typename std::iterator_traits<ITER>::iterator_category
iterator_category;
typedef size_t size_type;
typedef tab_ref_reg_spaced_iterator_<ITER> iterator;
ITER it;
size_type N, i;
iterator operator ++(int) { iterator tmp = *this; i++; return tmp; }
iterator operator --(int) { iterator tmp = *this; i--; return tmp; }
iterator &operator ++() { i++; return *this; }
iterator &operator --() { i--; return *this; }
iterator &operator +=(difference_type ii) { i+=ii; return *this; }
iterator &operator -=(difference_type ii) { i-=ii; return *this; }
iterator operator +(difference_type ii) const
{ iterator itt = *this; return (itt += ii); }
iterator operator -(difference_type ii) const
{ iterator itt = *this; return (itt -= ii); }
difference_type operator -(const iterator &ii) const
{ return (N ? (it - ii.it) / N : 0) + i - ii.i; }
reference operator *() const { return *(it + i*N); }
reference operator [](int ii) const { return *(it + (i+ii)*N); }
bool operator ==(const iterator &ii) const
{ return (*this - ii) == difference_type(0); }
bool operator !=(const iterator &ii) const
{ return (*this - ii) != difference_type(0); }
bool operator < (const iterator &ii) const
{ return (*this - ii) < difference_type(0); }
tab_ref_reg_spaced_iterator_(void) {}
tab_ref_reg_spaced_iterator_(const ITER &iter, size_type n, size_type ii)
: it(iter), N(n), i(ii) { }
};
/**
convenience template function for quick obtention of a strided iterator
without having to specify its (long) typename
*/
template<typename ITER> tab_ref_reg_spaced_iterator_<ITER>
reg_spaced_iterator(ITER it, size_t stride) {
return tab_ref_reg_spaced_iterator_<ITER>(it, stride);
}
/**
provide a "strided" view a of container
*/
template<typename ITER> class tab_ref_reg_spaced {
public :
typedef typename std::iterator_traits<ITER>::value_type value_type;
typedef typename std::iterator_traits<ITER>::pointer pointer;
typedef typename std::iterator_traits<ITER>::pointer const_pointer;
typedef typename std::iterator_traits<ITER>::reference reference;
typedef typename std::iterator_traits<ITER>::reference const_reference;
typedef typename std::iterator_traits<ITER>::difference_type
difference_type;
typedef size_t size_type;
typedef tab_ref_reg_spaced_iterator_<ITER> iterator;
typedef iterator const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
protected :
ITER begin_;
size_type N, size_;
public :
bool empty(void) const { return size_ == 0; }
size_type size(void) const { return size_; }
iterator begin(void) { return iterator(begin_, N, 0); }
const_iterator begin(void) const { return iterator(begin_, N, 0); }
iterator end(void) { return iterator(begin_, N, size_); }
const_iterator end(void) const { return iterator(begin_, N, size_); }
reverse_iterator rbegin(void) { return reverse_iterator(end()); }
const_reverse_iterator rbegin(void) const
{ return const_reverse_iterator(end()); }
reverse_iterator rend(void) { return reverse_iterator(begin()); }
const_reverse_iterator rend(void) const
{ return const_reverse_iterator(begin()); }
reference front(void) { return *begin_; }
const_reference front(void) const { return *begin_; }
reference back(void) { return *(begin_ + N * (size_-1)); }
const_reference back(void) const { return *(begin_ + N * (size_-1)); }
void pop_front(void) { begin_ += N; }
tab_ref_reg_spaced(void) {}
tab_ref_reg_spaced(const ITER &b, size_type n, size_type s)
: begin_(b), N(n), size_(s) {}
const_reference operator [](size_type ii) const
{ return *(begin_ + ii * N);}
reference operator [](size_type ii) { return *(begin_ + ii * N); }
};
/// iterator over a tab_ref_with_selection
template<typename ITER, typename COND>
struct tab_ref_with_selection_iterator_ : public ITER {
typedef typename std::iterator_traits<ITER>::value_type value_type;
typedef typename std::iterator_traits<ITER>::pointer pointer;
typedef typename std::iterator_traits<ITER>::reference reference;
typedef typename std::iterator_traits<ITER>::difference_type
difference_type;
typedef std::forward_iterator_tag iterator_category;
typedef tab_ref_with_selection_iterator_<ITER, COND> iterator;
const COND cond;
void forward(void) { while (!(cond)(*this)) ITER::operator ++(); }
iterator &operator ++()
{ ITER::operator ++(); forward(); return *this; }
iterator operator ++(int)
{ iterator tmp = *this; ++(*this); return tmp; }
tab_ref_with_selection_iterator_(void) {}
tab_ref_with_selection_iterator_(const ITER &iter, const COND c)
: ITER(iter), cond(c) {}
};
/**
given a container X and a predicate P, provide pseudo-container Y
of all elements of X such that P(X[i]).
*/
template<typename ITER, typename COND> class tab_ref_with_selection {
protected :
ITER begin_, end_;
COND cond;
public :
typedef typename std::iterator_traits<ITER>::value_type value_type;
typedef typename std::iterator_traits<ITER>::pointer pointer;
typedef typename std::iterator_traits<ITER>::pointer const_pointer;
typedef typename std::iterator_traits<ITER>::reference reference;
typedef typename std::iterator_traits<ITER>::reference const_reference;
typedef size_t size_type;
typedef tab_ref_with_selection_iterator_<ITER, COND> iterator;
typedef iterator const_iterator;
iterator begin(void) const
{ iterator it(begin_, cond); it.forward(); return it; }
iterator end(void) const { return iterator(end_, cond); }
bool empty(void) const { return begin_ == end_; }
value_type front(void) const { return *begin(); }
void pop_front(void) { ++begin_; begin_ = begin(); }
COND &condition(void) { return cond; }
const COND &condition(void) const { return cond; }
tab_ref_with_selection(void) {}
tab_ref_with_selection(const ITER &b, const ITER &e, const COND &c)
: begin_(b), end_(e), cond(c) { begin_ = begin(); }
};
}
#endif /* GMM_REF_H__ */