Reference documentation for deal.II version 9.1.0-pre
filtered_iterator.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2002 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_filtered_iterator_h
17 # define dealii_filtered_iterator_h
18 
19 
20 # include <deal.II/base/config.h>
21 
22 # include <deal.II/base/exceptions.h>
23 # include <deal.II/base/iterator_range.h>
24 # include <deal.II/base/std_cxx14/memory.h>
25 
26 # include <deal.II/grid/tria_iterator_base.h>
27 
28 # include <set>
29 # include <tuple>
30 
31 DEAL_II_NAMESPACE_OPEN
32 
33 
50 namespace IteratorFilters
51 {
58  class Active
59  {
60  public:
65  template <class Iterator>
66  bool
67  operator()(const Iterator &i) const;
68  };
69 
79  {
80  public:
85  template <class Iterator>
86  bool
87  operator()(const Iterator &i) const;
88  };
89 
90 
99  {
100  public:
105  template <class Iterator>
106  bool
107  operator()(const Iterator &i) const;
108  };
109 
110 
119  {
120  public:
125  LevelEqualTo(const unsigned int level);
126 
132  template <class Iterator>
133  bool
134  operator()(const Iterator &i) const;
135 
136  protected:
140  const unsigned int level;
141  };
142 
143 
144 
154  {
155  public:
160  SubdomainEqualTo(const types::subdomain_id subdomain_id);
161 
167  template <class Iterator>
168  bool
169  operator()(const Iterator &i) const;
170 
171  protected:
176  };
177 
178 
179 
192  {
193  public:
197  template <class Iterator>
198  bool
199  operator()(const Iterator &i) const;
200  };
201 
202 
203 
211  {
212  public:
217  template <class Iterator>
218  bool
219  operator()(const Iterator &i) const;
220  };
221 
222 
233  {
234  public:
239  MaterialIdEqualTo(const types::material_id material_id,
240  const bool only_locally_owned = false);
241 
247  MaterialIdEqualTo(const std::set<types::material_id> &material_ids,
248  const bool only_locally_owned = false);
249 
255  template <class Iterator>
256  bool
257  operator()(const Iterator &i) const;
258 
259  protected:
263  const std::set<types::material_id> material_ids;
267  const bool only_locally_owned;
268  };
269 
280  {
281  public:
286  ActiveFEIndexEqualTo(const unsigned int active_fe_index,
287  const bool only_locally_owned = false);
288 
294  ActiveFEIndexEqualTo(const std::set<unsigned int> &active_fe_indices,
295  const bool only_locally_owned = false);
296 
302  template <class Iterator>
303  bool
304  operator()(const Iterator &i) const;
305 
306  protected:
310  const std::set<unsigned int> active_fe_indices;
314  const bool only_locally_owned;
315  };
316 
326  {
327  public:
331  template <class Iterator>
332  bool
333  operator()(const Iterator &i) const;
334  };
335 } // namespace IteratorFilters
336 
337 
528 template <typename BaseIterator>
529 class FilteredIterator : public BaseIterator
530 {
531 public:
535  using AccessorType = typename BaseIterator::AccessorType;
536 
541  template <typename Predicate>
542  FilteredIterator(Predicate p);
543 
561  template <typename Predicate>
562  FilteredIterator(Predicate p, const BaseIterator &bi);
563 
569 
573  ~FilteredIterator();
574 
582  operator=(const FilteredIterator &fi);
583 
590  operator=(const BaseIterator &fi);
591 
601  set_to_next_positive(const BaseIterator &bi);
602 
612  set_to_previous_positive(const BaseIterator &bi);
613 
620  bool
621  operator==(const FilteredIterator &fi) const;
622 
629  bool
630  operator==(const BaseIterator &fi) const;
631 
638  bool
639  operator!=(const FilteredIterator &fi) const;
640 
647  bool
648  operator!=(const BaseIterator &fi) const;
649 
656  bool
657  operator<(const FilteredIterator &fi) const;
658 
665  bool
666  operator<(const BaseIterator &fi) const;
667 
673  operator++();
674 
680  operator++(int);
681 
687  operator--();
688 
694  operator--(int);
695 
700  ExcInvalidElement,
701  BaseIterator,
702  << "The element " << arg1
703  << " with which you want to compare or which you want to"
704  << " assign from is invalid since it does not satisfy the predicate.");
705 
706 private:
717  {
718  public:
723  virtual ~PredicateBase() = default;
724 
729  virtual bool
730  operator()(const BaseIterator &bi) const = 0;
731 
736  virtual std::unique_ptr<PredicateBase>
737  clone() const = 0;
738  };
739 
740 
749  template <typename Predicate>
751  {
752  public:
756  PredicateTemplate(const Predicate &predicate);
757 
761  virtual bool
762  operator()(const BaseIterator &bi) const override;
763 
768  virtual std::unique_ptr<PredicateBase>
769  clone() const override;
770 
771  private:
775  const Predicate predicate;
776  };
777 
782  std::unique_ptr<const PredicateBase> predicate;
783 };
784 
785 
786 
796 template <typename BaseIterator, typename Predicate>
798 make_filtered_iterator(const BaseIterator &i, const Predicate &p)
799 {
801  fi.set_to_next_positive(i);
802  return fi;
803 }
804 
805 
806 
807 namespace internal
808 {
809  namespace FilteredIteratorImplementation
810  {
811  // The following classes create a nested sequence of
812  // FilteredIterator<FilteredIterator<...<BaseIterator>...>> with as many
813  // levels of FilteredIterator classes as there are elements in the TypeList
814  // if the latter is given as a std::tuple<Args...>.
815  template <typename BaseIterator, typename TypeList>
816  struct NestFilteredIterators;
817 
818  template <typename BaseIterator, typename Predicate>
819  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate>>
820  {
822  };
823 
824  template <typename BaseIterator, typename Predicate, typename... Targs>
825  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>
826  {
827  using type = ::FilteredIterator<
828  typename NestFilteredIterators<BaseIterator,
829  std::tuple<Targs...>>::type>;
830  };
831  } // namespace FilteredIteratorImplementation
832 } // namespace internal
833 
834 
835 
869 template <typename BaseIterator, typename Predicate>
872 {
874  FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
875 
877 }
878 
879 
880 
918 template <typename BaseIterator, typename Predicate, typename... Targs>
920  typename internal::FilteredIteratorImplementation::
921  NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>::type>
923  const Predicate & p,
924  const Targs... args)
925 {
926  // Recursively create filtered iterators, one predicate at a time
927  auto fi = filter_iterators(i, p);
928  return filter_iterators(fi, args...);
929 }
930 
931 
932 /* ------------------ Inline functions and templates ------------ */
933 
934 
935 template <typename BaseIterator>
936 template <typename Predicate>
938  : predicate(new PredicateTemplate<Predicate>(p))
939 {}
940 
941 
942 
943 template <typename BaseIterator>
944 template <typename Predicate>
946  const BaseIterator &bi)
947  : BaseIterator(bi)
948  , predicate(new PredicateTemplate<Predicate>(p))
949 {
950  if ((this->state() == IteratorState::valid) && !(*predicate)(*this))
952 }
953 
954 
955 
956 template <typename BaseIterator>
958  const FilteredIterator &fi)
959  : // this construction looks strange, but without going through the
960  // address of fi, GCC would not cast fi to the base class of type
961  // BaseIterator but tries to go through constructing a new
962  // BaseIterator with an Accessor.
963  BaseIterator(*(BaseIterator *)(&fi))
964  , predicate(fi.predicate->clone())
965 {}
966 
967 
968 
969 template <typename BaseIterator>
971 {
972  predicate.reset();
973 }
974 
975 
976 
977 template <typename BaseIterator>
980 {
981  // Using equivalent code to the one for 'operator=(const BaseIterator &bi)'
982  // below, some compiler would not cast fi to the base class of type
983  // BaseIterator but try to go through constructing a new Accessor from fi
984  // which fails. Hence, we just use an explicit upcast and call the above-
985  // mentioned method.
986  const BaseIterator &bi = fi;
987  return operator=(bi);
988 }
989 
990 
991 
992 template <typename BaseIterator>
995 {
996  Assert((bi.state() != IteratorState::valid) || (*predicate)(bi),
997  ExcInvalidElement(bi));
998  BaseIterator::operator=(bi);
999  return *this;
1000 }
1001 
1002 
1003 
1004 template <typename BaseIterator>
1007 {
1008  BaseIterator::operator=(bi);
1009  while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1010  BaseIterator::operator++();
1011 
1012  return *this;
1013 }
1014 
1015 
1016 
1017 template <typename BaseIterator>
1020 {
1021  BaseIterator::operator=(bi);
1022  while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
1023  BaseIterator::operator--();
1024 
1025  return *this;
1026 }
1027 
1028 
1029 
1030 template <typename BaseIterator>
1031 inline bool
1033 {
1034  return (static_cast<const BaseIterator &>(*this) ==
1035  static_cast<const BaseIterator &>(fi));
1036 }
1037 
1038 
1039 
1040 template <typename BaseIterator>
1041 inline bool
1043 {
1044  return (static_cast<const BaseIterator &>(*this) !=
1045  static_cast<const BaseIterator &>(fi));
1046 }
1047 
1048 
1049 
1050 template <typename BaseIterator>
1051 inline bool
1053 {
1054  return (static_cast<const BaseIterator &>(*this) <
1055  static_cast<const BaseIterator &>(fi));
1056 }
1057 
1058 
1059 
1060 template <typename BaseIterator>
1061 inline bool
1062 FilteredIterator<BaseIterator>::operator==(const BaseIterator &bi) const
1063 {
1064  return (static_cast<const BaseIterator &>(*this) == bi);
1065 }
1066 
1067 
1068 
1069 template <typename BaseIterator>
1070 inline bool
1071 FilteredIterator<BaseIterator>::operator!=(const BaseIterator &bi) const
1072 {
1073  return (static_cast<const BaseIterator &>(*this) != bi);
1074 }
1075 
1076 
1077 
1078 template <typename BaseIterator>
1079 inline bool
1080 FilteredIterator<BaseIterator>::operator<(const BaseIterator &bi) const
1081 {
1082  return (static_cast<const BaseIterator &>(*this) < bi);
1083 }
1084 
1085 
1086 template <typename BaseIterator>
1089 {
1090  if (this->state() == IteratorState::valid)
1091  do
1092  BaseIterator::operator++();
1093  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1094  return *this;
1095 }
1096 
1097 
1098 
1099 template <typename BaseIterator>
1102 {
1103  const FilteredIterator old_state = *this;
1104 
1105  if (this->state() == IteratorState::valid)
1106  do
1107  BaseIterator::operator++();
1108  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1109  return old_state;
1110 }
1111 
1112 
1113 
1114 template <typename BaseIterator>
1117 {
1118  if (this->state() == IteratorState::valid)
1119  do
1120  BaseIterator::operator--();
1121  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1122  return *this;
1123 }
1124 
1125 
1126 
1127 template <typename BaseIterator>
1130 {
1131  const FilteredIterator old_state = *this;
1132 
1133  if (this->state() == IteratorState::valid)
1134  do
1135  BaseIterator::operator--();
1136  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1137  return old_state;
1138 }
1139 
1140 
1141 
1142 template <typename BaseIterator>
1143 template <typename Predicate>
1145  Predicate>::PredicateTemplate(const Predicate &predicate)
1146  : predicate(predicate)
1147 {}
1148 
1149 
1150 
1151 template <typename BaseIterator>
1152 template <typename Predicate>
1153 bool
1155 operator()(const BaseIterator &bi) const
1156 {
1157  return predicate(bi);
1158 }
1159 
1160 
1161 
1162 template <typename BaseIterator>
1163 template <typename Predicate>
1164 std::unique_ptr<typename FilteredIterator<BaseIterator>::PredicateBase>
1166 {
1167  return std_cxx14::make_unique<PredicateTemplate>(predicate);
1168 }
1169 
1170 
1171 
1172 namespace IteratorFilters
1173 {
1174  // ---------------- IteratorFilters::Active ---------
1175 
1176  template <class Iterator>
1177  inline bool
1178  Active::operator()(const Iterator &i) const
1179  {
1180  return (i->active());
1181  }
1182 
1183 
1184  // ---------------- IteratorFilters::UserFlagSet ---------
1185 
1186  template <class Iterator>
1187  inline bool
1188  UserFlagSet::operator()(const Iterator &i) const
1189  {
1190  return (i->user_flag_set());
1191  }
1192 
1193 
1194  // ---------------- IteratorFilters::UserFlagNotSet ---------
1195 
1196  template <class Iterator>
1197  inline bool
1198  UserFlagNotSet::operator()(const Iterator &i) const
1199  {
1200  return (!i->user_flag_set());
1201  }
1202 
1203 
1204  // ---------------- IteratorFilters::LevelEqualTo ---------
1205  inline LevelEqualTo::LevelEqualTo(const unsigned int level)
1206  : level(level)
1207  {}
1208 
1209 
1210 
1211  template <class Iterator>
1212  inline bool
1213  LevelEqualTo::operator()(const Iterator &i) const
1214  {
1215  return (static_cast<unsigned int>(i->level()) == level);
1216  }
1217 
1218 
1219 
1220  // ---------------- IteratorFilters::SubdomainEqualTo ---------
1222  const types::subdomain_id subdomain_id)
1223  : subdomain_id(subdomain_id)
1224  {}
1225 
1226 
1227 
1228  template <class Iterator>
1229  inline bool
1230  SubdomainEqualTo::operator()(const Iterator &i) const
1231  {
1232  return (i->subdomain_id() == subdomain_id);
1233  }
1234 
1235 
1236 
1237  // ---------------- IteratorFilters::LocallyOwnedCell ---------
1238 
1239  template <class Iterator>
1240  inline bool
1241  LocallyOwnedCell::operator()(const Iterator &i) const
1242  {
1243  return (i->is_locally_owned());
1244  }
1245 
1246 
1247  // ---------------- IteratorFilters::LocallyOwnedLevelCell ---------
1248 
1249  template <class Iterator>
1250  inline bool
1251  LocallyOwnedLevelCell::operator()(const Iterator &i) const
1252  {
1253  return (i->is_locally_owned_on_level());
1254  }
1255 
1256 
1257 
1258  // ---------------- IteratorFilters::MaterialIdEqualTo ---------
1260  const types::material_id material_id,
1261  const bool only_locally_owned)
1262  : material_ids{material_id}
1264  {}
1265 
1266 
1267 
1269  const std::set<types::material_id> &material_ids,
1270  const bool only_locally_owned)
1271  : material_ids(material_ids)
1272  , only_locally_owned(only_locally_owned)
1273  {}
1274 
1275 
1276 
1277  template <class Iterator>
1278  inline bool
1279  MaterialIdEqualTo::operator()(const Iterator &i) const
1280  {
1281  return only_locally_owned == true ?
1282  (material_ids.find(i->material_id()) != material_ids.end() &&
1283  i->is_locally_owned()) :
1284  material_ids.find(i->material_id()) != material_ids.end();
1285  }
1286 
1287 
1288 
1289  // ---------------- IteratorFilters::ActiveFEIndexEqualTo ---------
1291  const unsigned int active_fe_index,
1292  const bool only_locally_owned)
1293  : active_fe_indices{active_fe_index}
1295  {}
1296 
1297 
1298 
1300  const std::set<unsigned int> &active_fe_indices,
1301  const bool only_locally_owned)
1302  : active_fe_indices(active_fe_indices)
1303  , only_locally_owned(only_locally_owned)
1304  {}
1305 
1306 
1307 
1308  template <class Iterator>
1309  inline bool
1310  ActiveFEIndexEqualTo::operator()(const Iterator &i) const
1311  {
1312  return only_locally_owned == true ?
1313  (active_fe_indices.find(i->active_fe_index()) !=
1314  active_fe_indices.end() &&
1315  i->is_locally_owned()) :
1316  active_fe_indices.find(i->active_fe_index()) !=
1317  active_fe_indices.end();
1318  }
1319 
1320 
1321 
1322  // ---------------- IteratorFilters::AtBoundary ---------
1323 
1324  template <class Iterator>
1325  inline bool
1326  AtBoundary::operator()(const Iterator &i) const
1327  {
1328  return (i->at_boundary());
1329  }
1330 } // namespace IteratorFilters
1331 
1332 
1333 DEAL_II_NAMESPACE_CLOSE
1334 
1335 /*------------------------- filtered_iterator.h ------------------------*/
1336 #endif
1337 /*------------------------- filtered_iterator.h ------------------------*/
bool operator()(const Iterator &i) const
FilteredIterator & operator++()
IteratorOverIterators begin()
const types::subdomain_id subdomain_id
FilteredIterator(Predicate p)
bool operator()(const Iterator &i) const
unsigned int material_id
Definition: types.h:134
IteratorOverIterators end()
IteratorRange< FilteredIterator< BaseIterator > > filter_iterators(IteratorRange< BaseIterator > i, const Predicate &p)
FilteredIterator & operator--()
const std::set< types::material_id > material_ids
bool operator()(const Iterator &i) const
unsigned int subdomain_id
Definition: types.h:43
FilteredIterator & operator=(const FilteredIterator &fi)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:408
#define Assert(cond, exc)
Definition: exceptions.h:1227
bool operator==(const FilteredIterator &fi) const
std::unique_ptr< const PredicateBase > predicate
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const
MaterialIdEqualTo(const types::material_id material_id, const bool only_locally_owned=false)
const std::set< unsigned int > active_fe_indices
FilteredIterator & set_to_next_positive(const BaseIterator &bi)
SubdomainEqualTo(const types::subdomain_id subdomain_id)
bool operator<(const FilteredIterator &fi) const
static::ExceptionBase & ExcInvalidElement(BaseIterator arg1)
bool operator!=(const FilteredIterator &fi) const
ActiveFEIndexEqualTo(const unsigned int active_fe_index, const bool only_locally_owned=false)
Iterator points to a valid object.
FilteredIterator & set_to_previous_positive(const BaseIterator &bi)
FilteredIterator< BaseIterator > make_filtered_iterator(const BaseIterator &i, const Predicate &p)
typename BaseIterator::AccessorType AccessorType
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const