Reference documentation for deal.II version Git 7026f387cc 2019-10-15 14:19:01 -0400
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
filtered_iterator.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2002 - 2019 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 
577  operator=(const FilteredIterator &fi);
578 
585  operator=(const BaseIterator &fi);
586 
596  set_to_next_positive(const BaseIterator &bi);
597 
607  set_to_previous_positive(const BaseIterator &bi);
608 
615  bool
616  operator==(const FilteredIterator &fi) const;
617 
624  bool
625  operator==(const BaseIterator &fi) const;
626 
633  bool
634  operator!=(const FilteredIterator &fi) const;
635 
642  bool
643  operator!=(const BaseIterator &fi) const;
644 
651  bool
652  operator<(const FilteredIterator &fi) const;
653 
660  bool
661  operator<(const BaseIterator &fi) const;
662 
668  operator++();
669 
675  operator++(int);
676 
682  operator--();
683 
689  operator--(int);
690 
695  ExcInvalidElement,
696  BaseIterator,
697  << "The element " << arg1
698  << " with which you want to compare or which you want to"
699  << " assign from is invalid since it does not satisfy the predicate.");
700 
701 private:
712  {
713  public:
718  virtual ~PredicateBase() = default;
719 
724  virtual bool
725  operator()(const BaseIterator &bi) const = 0;
726 
731  virtual std::unique_ptr<PredicateBase>
732  clone() const = 0;
733  };
734 
735 
744  template <typename Predicate>
746  {
747  public:
751  PredicateTemplate(const Predicate &predicate);
752 
756  virtual bool
757  operator()(const BaseIterator &bi) const override;
758 
763  virtual std::unique_ptr<PredicateBase>
764  clone() const override;
765 
766  private:
770  const Predicate predicate;
771  };
772 
777  std::unique_ptr<const PredicateBase> predicate;
778 };
779 
780 
781 
791 template <typename BaseIterator, typename Predicate>
793 make_filtered_iterator(const BaseIterator &i, const Predicate &p)
794 {
796  fi.set_to_next_positive(i);
797  return fi;
798 }
799 
800 
801 
802 namespace internal
803 {
804  namespace FilteredIteratorImplementation
805  {
806  // The following classes create a nested sequence of
807  // FilteredIterator<FilteredIterator<...<BaseIterator>...>> with as many
808  // levels of FilteredIterator classes as there are elements in the TypeList
809  // if the latter is given as a std::tuple<Args...>.
810  template <typename BaseIterator, typename TypeList>
811  struct NestFilteredIterators;
812 
813  template <typename BaseIterator, typename Predicate>
814  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate>>
815  {
817  };
818 
819  template <typename BaseIterator, typename Predicate, typename... Targs>
820  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>
821  {
822  using type = ::FilteredIterator<
823  typename NestFilteredIterators<BaseIterator,
824  std::tuple<Targs...>>::type>;
825  };
826  } // namespace FilteredIteratorImplementation
827 } // namespace internal
828 
829 
830 
864 template <typename BaseIterator, typename Predicate>
867 {
869  FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
870 
872 }
873 
874 
875 
913 template <typename BaseIterator, typename Predicate, typename... Targs>
915  typename internal::FilteredIteratorImplementation::
916  NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...>>::type>
918  const Predicate & p,
919  const Targs... args)
920 {
921  // Recursively create filtered iterators, one predicate at a time
922  auto fi = filter_iterators(i, p);
923  return filter_iterators(fi, args...);
924 }
925 
926 
927 /* ------------------ Inline functions and templates ------------ */
928 
929 
930 template <typename BaseIterator>
931 template <typename Predicate>
933  : predicate(new PredicateTemplate<Predicate>(p))
934 {}
935 
936 
937 
938 template <typename BaseIterator>
939 template <typename Predicate>
941  const BaseIterator &bi)
942  : BaseIterator(bi)
943  , predicate(new PredicateTemplate<Predicate>(p))
944 {
945  if ((this->state() == IteratorState::valid) && !(*predicate)(*this))
947 }
948 
949 
950 
951 template <typename BaseIterator>
953  const FilteredIterator &fi)
954  : // this construction looks strange, but without going through the
955  // address of fi, GCC would not cast fi to the base class of type
956  // BaseIterator but tries to go through constructing a new
957  // BaseIterator with an Accessor.
958  BaseIterator(*static_cast<const BaseIterator *>(&fi))
959  , predicate(fi.predicate->clone())
960 {}
961 
962 
963 
964 template <typename BaseIterator>
967 {
968  // Using equivalent code to the one for 'operator=(const BaseIterator &bi)'
969  // below, some compiler would not cast fi to the base class of type
970  // BaseIterator but try to go through constructing a new Accessor from fi
971  // which fails. Hence, we just use an explicit upcast and call the above-
972  // mentioned method.
973  const BaseIterator &bi = fi;
974  return operator=(bi);
975 }
976 
977 
978 
979 template <typename BaseIterator>
982 {
983  Assert((bi.state() != IteratorState::valid) || (*predicate)(bi),
984  ExcInvalidElement(bi));
985  BaseIterator::operator=(bi);
986  return *this;
987 }
988 
989 
990 
991 template <typename BaseIterator>
994 {
995  BaseIterator::operator=(bi);
996  while ((this->state() == IteratorState::valid) && (!(*predicate)(*this)))
997  BaseIterator::operator++();
998 
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>
1018 inline bool
1020 {
1021  return (static_cast<const BaseIterator &>(*this) ==
1022  static_cast<const BaseIterator &>(fi));
1023 }
1024 
1025 
1026 
1027 template <typename BaseIterator>
1028 inline bool
1030 {
1031  return (static_cast<const BaseIterator &>(*this) !=
1032  static_cast<const BaseIterator &>(fi));
1033 }
1034 
1035 
1036 
1037 template <typename BaseIterator>
1038 inline bool
1040 {
1041  return (static_cast<const BaseIterator &>(*this) <
1042  static_cast<const BaseIterator &>(fi));
1043 }
1044 
1045 
1046 
1047 template <typename BaseIterator>
1048 inline bool
1049 FilteredIterator<BaseIterator>::operator==(const BaseIterator &bi) const
1050 {
1051  return (static_cast<const BaseIterator &>(*this) == bi);
1052 }
1053 
1054 
1055 
1056 template <typename BaseIterator>
1057 inline bool
1058 FilteredIterator<BaseIterator>::operator!=(const BaseIterator &bi) const
1059 {
1060  return (static_cast<const BaseIterator &>(*this) != bi);
1061 }
1062 
1063 
1064 
1065 template <typename BaseIterator>
1066 inline bool
1067 FilteredIterator<BaseIterator>::operator<(const BaseIterator &bi) const
1068 {
1069  return (static_cast<const BaseIterator &>(*this) < bi);
1070 }
1071 
1072 
1073 template <typename BaseIterator>
1076 {
1077  if (this->state() == IteratorState::valid)
1078  do
1079  BaseIterator::operator++();
1080  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1081  return *this;
1082 }
1083 
1084 
1085 
1086 template <typename BaseIterator>
1089 {
1090  const FilteredIterator old_state = *this;
1091 
1092  if (this->state() == IteratorState::valid)
1093  do
1094  BaseIterator::operator++();
1095  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1096  return old_state;
1097 }
1098 
1099 
1100 
1101 template <typename BaseIterator>
1104 {
1105  if (this->state() == IteratorState::valid)
1106  do
1107  BaseIterator::operator--();
1108  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1109  return *this;
1110 }
1111 
1112 
1113 
1114 template <typename BaseIterator>
1117 {
1118  const FilteredIterator old_state = *this;
1119 
1120  if (this->state() == IteratorState::valid)
1121  do
1122  BaseIterator::operator--();
1123  while ((this->state() == IteratorState::valid) && !(*predicate)(*this));
1124  return old_state;
1125 }
1126 
1127 
1128 
1129 template <typename BaseIterator>
1130 template <typename Predicate>
1132  Predicate>::PredicateTemplate(const Predicate &predicate)
1133  : predicate(predicate)
1134 {}
1135 
1136 
1137 
1138 template <typename BaseIterator>
1139 template <typename Predicate>
1140 bool
1142 operator()(const BaseIterator &bi) const
1143 {
1144  return predicate(bi);
1145 }
1146 
1147 
1148 
1149 template <typename BaseIterator>
1150 template <typename Predicate>
1151 std::unique_ptr<typename FilteredIterator<BaseIterator>::PredicateBase>
1153 {
1154  return std_cxx14::make_unique<PredicateTemplate>(predicate);
1155 }
1156 
1157 
1158 
1159 namespace IteratorFilters
1160 {
1161  // ---------------- IteratorFilters::Active ---------
1162 
1163  template <class Iterator>
1164  inline bool
1165  Active::operator()(const Iterator &i) const
1166  {
1167  return (i->active());
1168  }
1169 
1170 
1171  // ---------------- IteratorFilters::UserFlagSet ---------
1172 
1173  template <class Iterator>
1174  inline bool
1175  UserFlagSet::operator()(const Iterator &i) const
1176  {
1177  return (i->user_flag_set());
1178  }
1179 
1180 
1181  // ---------------- IteratorFilters::UserFlagNotSet ---------
1182 
1183  template <class Iterator>
1184  inline bool
1185  UserFlagNotSet::operator()(const Iterator &i) const
1186  {
1187  return (!i->user_flag_set());
1188  }
1189 
1190 
1191  // ---------------- IteratorFilters::LevelEqualTo ---------
1192  inline LevelEqualTo::LevelEqualTo(const unsigned int level)
1193  : level(level)
1194  {}
1195 
1196 
1197 
1198  template <class Iterator>
1199  inline bool
1200  LevelEqualTo::operator()(const Iterator &i) const
1201  {
1202  return (static_cast<unsigned int>(i->level()) == level);
1203  }
1204 
1205 
1206 
1207  // ---------------- IteratorFilters::SubdomainEqualTo ---------
1209  const types::subdomain_id subdomain_id)
1210  : subdomain_id(subdomain_id)
1211  {}
1212 
1213 
1214 
1215  template <class Iterator>
1216  inline bool
1217  SubdomainEqualTo::operator()(const Iterator &i) const
1218  {
1219  return (i->subdomain_id() == subdomain_id);
1220  }
1221 
1222 
1223 
1224  // ---------------- IteratorFilters::LocallyOwnedCell ---------
1225 
1226  template <class Iterator>
1227  inline bool
1228  LocallyOwnedCell::operator()(const Iterator &i) const
1229  {
1230  return (i->is_locally_owned());
1231  }
1232 
1233 
1234  // ---------------- IteratorFilters::LocallyOwnedLevelCell ---------
1235 
1236  template <class Iterator>
1237  inline bool
1238  LocallyOwnedLevelCell::operator()(const Iterator &i) const
1239  {
1240  return (i->is_locally_owned_on_level());
1241  }
1242 
1243 
1244 
1245  // ---------------- IteratorFilters::MaterialIdEqualTo ---------
1247  const types::material_id material_id,
1248  const bool only_locally_owned)
1249  : material_ids{material_id}
1251  {}
1252 
1253 
1254 
1256  const std::set<types::material_id> &material_ids,
1257  const bool only_locally_owned)
1258  : material_ids(material_ids)
1259  , only_locally_owned(only_locally_owned)
1260  {}
1261 
1262 
1263 
1264  template <class Iterator>
1265  inline bool
1266  MaterialIdEqualTo::operator()(const Iterator &i) const
1267  {
1268  return only_locally_owned == true ?
1269  (material_ids.find(i->material_id()) != material_ids.end() &&
1270  i->is_locally_owned()) :
1271  material_ids.find(i->material_id()) != material_ids.end();
1272  }
1273 
1274 
1275 
1276  // ---------------- IteratorFilters::ActiveFEIndexEqualTo ---------
1278  const unsigned int active_fe_index,
1279  const bool only_locally_owned)
1280  : active_fe_indices{active_fe_index}
1282  {}
1283 
1284 
1285 
1287  const std::set<unsigned int> &active_fe_indices,
1288  const bool only_locally_owned)
1289  : active_fe_indices(active_fe_indices)
1290  , only_locally_owned(only_locally_owned)
1291  {}
1292 
1293 
1294 
1295  template <class Iterator>
1296  inline bool
1297  ActiveFEIndexEqualTo::operator()(const Iterator &i) const
1298  {
1299  return only_locally_owned == true ?
1300  (active_fe_indices.find(i->active_fe_index()) !=
1301  active_fe_indices.end() &&
1302  i->is_locally_owned()) :
1303  active_fe_indices.find(i->active_fe_index()) !=
1304  active_fe_indices.end();
1305  }
1306 
1307 
1308 
1309  // ---------------- IteratorFilters::AtBoundary ---------
1310 
1311  template <class Iterator>
1312  inline bool
1313  AtBoundary::operator()(const Iterator &i) const
1314  {
1315  return (i->at_boundary());
1316  }
1317 } // namespace IteratorFilters
1318 
1319 
1320 DEAL_II_NAMESPACE_CLOSE
1321 
1322 /*------------------------- filtered_iterator.h ------------------------*/
1323 #endif
1324 /*------------------------- 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
bool operator==(const FilteredIterator &fi) const
bool operator()(const Iterator &i) const
unsigned int material_id
Definition: types.h:148
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:518
#define Assert(cond, exc)
Definition: exceptions.h:1407
bool operator()(const Iterator &i) const
std::unique_ptr< const PredicateBase > predicate
bool operator!=(const FilteredIterator &fi) const
MaterialIdEqualTo(const types::material_id material_id, const bool only_locally_owned=false)
bool operator()(const Iterator &i) const
const std::set< unsigned int > active_fe_indices
FilteredIterator & set_to_next_positive(const BaseIterator &bi)
SubdomainEqualTo(const types::subdomain_id subdomain_id)
static ::ExceptionBase & ExcInvalidElement(BaseIterator arg1)
bool operator()(const Iterator &i) 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)
bool operator<(const FilteredIterator &fi) const
FilteredIterator< BaseIterator > make_filtered_iterator(const BaseIterator &i, const Predicate &p)
typename BaseIterator::AccessorType AccessorType
bool operator()(const Iterator &i) const
IteratorOverIterators end() const