1#ifndef DUNE_MULTIDOMAINGRID_ARRAYBASEDSET_HH 
    2#define DUNE_MULTIDOMAINGRID_ARRAYBASEDSET_HH 
   13#include <dune/common/exceptions.hh> 
   19template<
typename SI, std::
size_t capacity>
 
   23template<
typename SI, std::
size_t capacity>
 
   24bool setContains(
const ArrayBasedSet<SI,capacity>& a,
 
   25                 const ArrayBasedSet<SI,capacity>& b);
 
   28template<
typename SI, std::
size_t capacity>
 
   29void setAdd(ArrayBasedSet<SI,capacity>& a,
 
   30            const ArrayBasedSet<SI,capacity>& b);
 
   33template<
typename SI, std::
size_t capacity>
 
   36  friend bool setContains<>(
const ArrayBasedSet<SI,capacity>& a,
 
   37                        const ArrayBasedSet<SI,capacity>& b);
 
   39  friend void setAdd<>(ArrayBasedSet<SI,capacity>& a,
 
   40                   const ArrayBasedSet<SI,capacity>& b);
 
   43  typedef SI SubDomainIndex;
 
   45  static const std::size_t maxSize = capacity;
 
   46  static const SubDomainIndex emptyTag = std::numeric_limits<SubDomainIndex>::max();
 
   47  typedef typename std::array<SubDomainIndex,maxSize>::iterator ArrayIterator;
 
   48  typedef typename std::array<SubDomainIndex,maxSize>::const_iterator Iterator;
 
   49  typedef ArrayBasedSet<SubDomainIndex,capacity> This;
 
   51  enum SetState {emptySet,simpleSet,multipleSet};
 
   55    typedef SubDomainIndex DataType;
 
   57    static bool fixedSize(
int dim, 
int codim)
 
   62    static std::size_t size(
const ArrayBasedSet& sds)
 
   67    template<
typename MessageBufferImp>
 
   68    static void gather(MessageBufferImp& buf, 
const ArrayBasedSet& sds)
 
   70      for(Iterator it = sds.begin(); it != sds.end(); ++it)
 
   74    template<
typename MessageBufferImp>
 
   75    static void scatter(MessageBufferImp& buf, ArrayBasedSet& sds, std::size_t n)
 
   79      ArrayIterator end = h._set.begin() + n;
 
   80      for (ArrayIterator it = h._set.begin(); it != end; ++it)
 
   87  Iterator begin()
 const {
 
   91  Iterator end()
 const {
 
   92    return _set.begin() + _size;
 
   95  bool contains(SubDomainIndex domain)
 const {
 
   96    return std::binary_search(_set.begin(),_set.begin() + _size,domain);
 
   99  template<
typename Set>
 
  100  bool containsAll(
const Set& set)
 const {
 
  101    return setContains(*
this,set);
 
  104  void difference(
const ArrayBasedSet& minuend, 
const ArrayBasedSet& subtrahend)
 
  106    Iterator res = std::set_difference(minuend.begin(),minuend.end(),
 
  107                                       subtrahend.begin(),subtrahend.end(),
 
  109    _size = res - _set.begin();
 
  112  bool simple()
 const {
 
  120  SetState state()
 const {
 
  131  std::size_t size()
 const {
 
  139  void add(SubDomainIndex domain) {
 
  140    if (!std::binary_search(_set.begin(),_set.begin()+_size,domain)) {
 
  141      assert(_size < maxSize);
 
  142      _set[_size++] = domain;
 
  143      std::sort(_set.begin(),_set.begin()+_size);
 
  147  void remove(SubDomainIndex domain) {
 
  148    ArrayIterator it = std::lower_bound(_set.begin(),_set.begin()+_size,domain);
 
  149    assert(*it == domain);
 
  151    std::sort(_set.begin(),_set.end() + (_size--));
 
  154  void set(SubDomainIndex domain) {
 
  159  template<
typename Set>
 
  160  void addAll(
const Set& set) {
 
  164  int domainOffset(SubDomainIndex domain)
 const {
 
  165    Iterator it = std::lower_bound(_set.begin(),_set.begin()+_size,domain);
 
  166    assert(*it == domain);
 
  167    return it - _set.begin();
 
  174  bool operator==(
const ArrayBasedSet& r)
 const {
 
  175    return _size == r._size && std::equal(_set.begin(),_set.begin()+_size,r._set.begin());
 
  178  bool operator!=(
const ArrayBasedSet& r)
 const {
 
  179    return !operator==(r);
 
  184  std::array<SubDomainIndex,maxSize> _set;
 
  189template<
typename SubDomainIndex, std::
size_t capacity>
 
  190inline bool setContains(
const ArrayBasedSet<SubDomainIndex,capacity>& a,
 
  191                        const ArrayBasedSet<SubDomainIndex,capacity>& b) {
 
  192  return std::includes(a._set.begin(),a._set.begin() + a._size,b._set.begin(),b._set.begin() + b._size);
 
  195template<
typename SubDomainIndex, std::
size_t capacity>
 
  196inline void setAdd(ArrayBasedSet<SubDomainIndex,capacity>& a,
 
  197                   const ArrayBasedSet<SubDomainIndex,capacity>& b) {
 
  198  std::array<SubDomainIndex,2*capacity> tmp;
 
  199  typename std::array<SubDomainIndex,2*capacity>::iterator it = std::set_union(a._set.begin(), a._set.begin() + a._size,
 
  200                                                                                   b._set.begin(), b._set.begin() + b._size,
 
  202  a._size = it - tmp.begin();
 
  203  assert(a._size <= capacity);
 
  204  std::copy(tmp.begin(),++it,a._set.begin());