1#ifndef DUNE_MULTIDOMAINGRID_SUBDOMAINSET_HH
2#define DUNE_MULTIDOMAINGRID_SUBDOMAINSET_HH
10#include <dune/common/typetraits.hh>
11#include <dune/common/iteratorfacades.hh>
12#include <dune/common/exceptions.hh>
21template<
typename SubDomainIndex, std::
size_t capacity>
22class IntegralTypeSubDomainSet;
24template<
typename SubDomainIndex, std::
size_t capacity>
25bool setContains(
const IntegralTypeSubDomainSet<SubDomainIndex,capacity>& a,
26 const IntegralTypeSubDomainSet<SubDomainIndex,capacity>& b);
28template<
typename SubDomainIndex, std::
size_t capacity>
29void setAdd(IntegralTypeSubDomainSet<SubDomainIndex,capacity>& a,
30 const IntegralTypeSubDomainSet<SubDomainIndex,capacity>& b);
43 struct Candidate<uint8_t> {
45 typedef Candidate<uint16_t> next_candidate;
50 struct Candidate<uint16_t> {
51 typedef uint16_t type;
52 typedef Candidate<uint32_t> next_candidate;
57 struct Candidate<uint32_t> {
58 typedef uint32_t type;
59 typedef Candidate<uint64_t> next_candidate;
64 struct Candidate<uint64_t> {
65 typedef uint64_t type;
66 typedef void next_candidate;
70 template<std::
size_t capacity,
typename cand
idate>
71 struct SetStorageTester {
73 static_assert(std::numeric_limits<typename candidate::type>::is_specialized,
"numeric_limits<> lacks specialization");
75 typedef typename std::conditional<capacity <= static_cast<std::size_t>(std::numeric_limits<typename candidate::type>::digits),
76 typename candidate::type,
77 typename SetStorageTester<capacity,
78 typename candidate::next_candidate
82 static_assert((!std::is_same<type,void>::value),
"unsupported maximum number of subdomains");
89 template<std::
size_t capacity>
90 struct SetStorageTester<capacity,void> {
97 template<std::
size_t capacity>
98 struct SetStorageChooser {
99 typedef typename SetStorageTester<capacity,Candidate<uint8_t> >::type type;
107 inline static std::size_t doCalculation(T value);
111 inline static std::size_t calculate(T value) {
112 assert(value != 0 && (value & (value-1)) == 0);
113 return doCalculation(value);
119 inline std::size_t Log2<uint8_t>::doCalculation(uint8_t value) {
120 return __builtin_ffs(value)-1;
125 inline std::size_t Log2<uint16_t>::doCalculation(uint16_t value) {
126 return __builtin_ffs(value)-1;
131 inline std::size_t Log2<uint32_t>::doCalculation(uint32_t value) {
132 return __builtin_ffsl(value)-1;
137 inline std::size_t Log2<uint64_t>::doCalculation(uint64_t value) {
138 return __builtin_ffsll(value)-1;
142 template<
typename SubDomainIndex,
typename SetStorage>
143 class Iterator :
public ForwardIteratorFacade<Iterator<SubDomainIndex,SetStorage>,
148 template<
typename,std::
size_t>
149 friend class ::Dune::mdgrid::IntegralTypeSubDomainSet;
153 typedef Iterator<SubDomainIndex,SetStorage> ThisType;
154 static const SetStorage base = 1;
156 SubDomainIndex dereference()
const {
161 bool equals(
const ThisType& rhs)
const {
162 return _state == rhs._state;
166 _state &= ~(base << _value);
174 void findNextValue() {
175 SetStorage lowestBit = _state & ((~_state) + 1);
176 _value = Log2<SetStorage>::calculate(lowestBit);
179 explicit Iterator(SetStorage state) :
188 explicit Iterator() :
194 SubDomainIndex _value;
203template<
typename SubDomainIndexT, std::
size_t capacity>
212 typedef typename sds_detail::SetStorageChooser<capacity>::type SetStorage;
213 static const SetStorage base = 1;
218 typedef sds_detail::Iterator<SubDomainIndex,SetStorage>
Iterator;
235 template<
typename MessageBufferImp>
241 template<
typename MessageBufferImp>
263 return (base << domain) & _set;
266 template<
typename Set>
273 _set = minuend._set & ~subtrahend._set;
277 return (!
empty()) && ((_set & (_set - 1)) == 0);
290 for (SetStorage t = _set; t; ++c) {
302 _set |= base << domain;
307 _set &= ~(base << domain);
312 _set = base << domain;
315 template<
typename Set>
321 assert(domain >= 0 && domain <
maxSize);
330 return _set == r._set;
343template<
typename A,
typename B>
345 return std::all_of(b.begin(),b.end(),[&a](
decltype(*(b.begin())) i) { return a.contains(i); });
348template<
typename A,
typename B>
350 std::for_each(b.begin(),b.end(),[&a](
decltype(*(b.begin())) i) { a.add(i); });
354template<
typename SubDomainIndex, std::
size_t capacity>
357 return (a._set & b._set) == b._set;
360template<
typename SubDomainIndex, std::
size_t capacity>
Definition: multidomaingrid.hh:8
bool setContains(const ArrayBasedSet< SI, capacity > &a, const ArrayBasedSet< SI, capacity > &b)
void setAdd(ArrayBasedSet< SI, capacity > &a, const ArrayBasedSet< SI, capacity > &b)
Definition: subdomainset.hh:204
bool operator!=(const IntegralTypeSubDomainSet &r) const
Definition: subdomainset.hh:333
friend bool setContains(const IntegralTypeSubDomainSet< SubDomainIndexT, capacity > &a, const IntegralTypeSubDomainSet< SubDomainIndexT, capacity > &b)
SubDomainIndexT SubDomainIndex
Definition: subdomainset.hh:217
bool containsAll(const Set &set) const
Definition: subdomainset.hh:267
Iterator begin() const
Definition: subdomainset.hh:253
bool empty() const
Definition: subdomainset.hh:280
void remove(SubDomainIndex domain)
Definition: subdomainset.hh:305
void difference(const IntegralTypeSubDomainSet &minuend, const IntegralTypeSubDomainSet &subtrahend)
Definition: subdomainset.hh:271
IntegralTypeSubDomainSet()
Definition: subdomainset.hh:325
SetState
Definition: subdomainset.hh:251
@ multipleSet
Definition: subdomainset.hh:251
@ simpleSet
Definition: subdomainset.hh:251
@ emptySet
Definition: subdomainset.hh:251
std::size_t size() const
Definition: subdomainset.hh:288
sds_detail::Iterator< SubDomainIndex, SetStorage > Iterator
Definition: subdomainset.hh:218
void add(SubDomainIndex domain)
Definition: subdomainset.hh:300
int domainOffset(SubDomainIndex domain) const
Definition: subdomainset.hh:320
friend void setAdd(IntegralTypeSubDomainSet< SubDomainIndexT, capacity > &a, const IntegralTypeSubDomainSet< SubDomainIndexT, capacity > &b)
IntegralTypeSubDomainSet< SubDomainIndex, capacity > This
Definition: subdomainset.hh:219
bool simple() const
Definition: subdomainset.hh:276
static const std::size_t maxSize
Definition: subdomainset.hh:216
Iterator end() const
Definition: subdomainset.hh:257
bool operator==(const IntegralTypeSubDomainSet &r) const
Definition: subdomainset.hh:329
bool contains(SubDomainIndex domain) const
Definition: subdomainset.hh:261
void addAll(const Set &rhs)
Definition: subdomainset.hh:316
void set(SubDomainIndex domain)
Definition: subdomainset.hh:310
void clear()
Definition: subdomainset.hh:296
SetState state() const
Definition: subdomainset.hh:284
Definition: subdomainset.hh:222
SetStorage DataType
Definition: subdomainset.hh:223
static void scatter(MessageBufferImp &buf, IntegralTypeSubDomainSet &sds, std::size_t n)
Definition: subdomainset.hh:242
static bool fixedSize(int dim, int codim)
Definition: subdomainset.hh:225
static std::size_t size(const IntegralTypeSubDomainSet &sds)
Definition: subdomainset.hh:230
static void gather(MessageBufferImp &buf, const IntegralTypeSubDomainSet &sds)
Definition: subdomainset.hh:236