Reference documentation for deal.II version 8.5.1
filtered_iterator.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2002 - 2017 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 at
12 // the top level of the deal.II distribution.
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 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/iterator_range.h>
23 #include <deal.II/grid/tria_iterator_base.h>
24 
25 #include <set>
26 #ifdef DEAL_II_WITH_CXX11
27 #include <tuple>
28 #endif
29 
30 DEAL_II_NAMESPACE_OPEN
31 
32 
49 namespace IteratorFilters
50 {
57  class Active
58  {
59  public:
64  template <class Iterator>
65  bool operator () (const Iterator &i) const;
66  };
67 
77  {
78  public:
83  template <class Iterator>
84  bool operator () (const Iterator &i) const;
85  };
86 
87 
96  {
97  public:
102  template <class Iterator>
103  bool operator () (const Iterator &i) const;
104  };
105 
106 
115  {
116  public:
121  LevelEqualTo (const unsigned int level);
122 
128  template <class Iterator>
129  bool operator () (const Iterator &i) const;
130 
131  protected:
135  const unsigned int level;
136  };
137 
138 
139 
149  {
150  public:
156 
162  template <class Iterator>
163  bool operator () (const Iterator &i) const;
164 
165  protected:
170  };
171 
172 
173 
186  {
187  public:
191  template <class Iterator>
192  bool operator () (const Iterator &i) const;
193  };
194 
195 
196 
204  {
205  public:
210  template <class Iterator>
211  bool operator () (const Iterator &i) const;
212  };
213 
214 
225  {
226  public:
231  MaterialIdEqualTo (const types::material_id material_id,
232  const bool only_locally_owned = false);
233 
239  MaterialIdEqualTo (const std::set<types::material_id> material_ids,
240  const bool only_locally_owned = false);
241 
247  template <class Iterator>
248  bool operator () (const Iterator &i) const;
249 
250  protected:
254  const std::set<types::material_id> material_ids;
258  const bool only_locally_owned;
259  };
260 
271  {
272  public:
277  ActiveFEIndexEqualTo (const unsigned int active_fe_index,
278  const bool only_locally_owned = false);
279 
285  ActiveFEIndexEqualTo (const std::set<unsigned int> active_fe_indices,
286  const bool only_locally_owned = false);
287 
293  template <class Iterator>
294  bool operator () (const Iterator &i) const;
295 
296  protected:
300  const std::set<unsigned int> active_fe_indices;
304  const bool only_locally_owned;
305  };
306 
316  {
317  public:
321  template <class Iterator>
322  bool operator () (const Iterator &i) const;
323  };
324 }
325 
326 
512 template <typename BaseIterator>
513 class FilteredIterator : public BaseIterator
514 {
515 public:
519  typedef typename BaseIterator::AccessorType AccessorType;
520 
525  template <typename Predicate>
526  FilteredIterator (Predicate p);
527 
545  template <typename Predicate>
546  FilteredIterator (Predicate p,
547  const BaseIterator &bi);
548 
554 
559 
567 
573  FilteredIterator &operator = (const BaseIterator &fi);
574 
584  set_to_next_positive (const BaseIterator &bi);
585 
595  set_to_previous_positive (const BaseIterator &bi);
596 
603  bool operator == (const FilteredIterator &fi) const;
604 
611  bool operator == (const BaseIterator &fi) const;
612 
619  bool operator != (const FilteredIterator &fi) const;
620 
627  bool operator != (const BaseIterator &fi) const;
628 
635  bool operator < (const FilteredIterator &fi) const;
636 
643  bool operator < (const BaseIterator &fi) const;
644 
650 
656 
662 
668 
673  BaseIterator,
674  << "The element " << arg1
675  << " with which you want to compare or which you want to"
676  << " assign from is invalid since it does not satisfy the predicate.");
677 
678 private:
679 
690  {
691  public:
696  virtual ~PredicateBase () {}
697 
702  virtual bool operator () (const BaseIterator &bi) const = 0;
703 
708  virtual PredicateBase *clone () const = 0;
709  };
710 
711 
720  template <typename Predicate>
722  {
723  public:
727  PredicateTemplate (const Predicate &predicate);
728 
732  virtual bool operator () (const BaseIterator &bi) const;
733 
738  virtual PredicateBase *clone () const;
739 
740  private:
744  const Predicate predicate;
745  };
746 
752 
753 };
754 
755 
756 
766 template <typename BaseIterator, typename Predicate>
768 make_filtered_iterator (const BaseIterator &i,
769  const Predicate &p)
770 {
772  fi.set_to_next_positive (i);
773  return fi;
774 }
775 
776 
777 
778 #ifdef DEAL_II_WITH_CXX11
779 namespace internal
780 {
781  namespace FilteredIterator
782  {
783  // The following classes create a nested sequencee of
784  // FilteredIterator<FilteredIterator<...<BaseIterator>...>> with as many
785  // levels of FilteredIterator classes as there are elements in the TypeList
786  // if the latter is given as a std::tuple<Args...>.
787  template <typename BaseIterator, typename TypeList>
788  struct NestFilteredIterators;
789 
790  template <typename BaseIterator, typename Predicate>
791  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate> >
792  {
793  typedef ::FilteredIterator<BaseIterator> type;
794  };
795 
796  template <typename BaseIterator, typename Predicate, typename... Targs>
797  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...> >
798  {
799  typedef ::FilteredIterator<typename NestFilteredIterators<BaseIterator,
800  std::tuple<Targs...> >::type> type;
801  };
802  }
803 }
804 
805 
806 
838 template <typename BaseIterator, typename Predicate>
841  const Predicate &p)
842 {
844  FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
845 
846  return IteratorRange<FilteredIterator<BaseIterator> > (fi, fi_end);
847 }
848 
849 
850 
886 template <typename BaseIterator, typename Predicate, typename... Targs>
887 IteratorRange<typename internal::FilteredIterator::
888 NestFilteredIterators<BaseIterator,std::tuple<Predicate, Targs...> >::type>
890  const Predicate &p,
891  const Targs... args)
892 {
893  // Recursively create filtered iterators, one predicate at a time
894  auto fi = filter_iterators(i,p);
895  return filter_iterators(fi, args...);
896 }
897 #endif
898 
899 
900 /* ------------------ Inline functions and templates ------------ */
901 
902 
903 template <typename BaseIterator>
904 template <typename Predicate>
905 inline
907 FilteredIterator (Predicate p)
908  :
909  predicate (new PredicateTemplate<Predicate>(p))
910 {}
911 
912 
913 
914 template <typename BaseIterator>
915 template <typename Predicate>
916 inline
918 FilteredIterator (Predicate p,
919  const BaseIterator &bi)
920  :
921  BaseIterator (bi),
922  predicate (new PredicateTemplate<Predicate>(p))
923 {
924  if ((this->state() == IteratorState::valid) &&
925  ! (*predicate) (*this))
927 }
928 
929 
930 
931 template <typename BaseIterator>
932 inline
935  :
936 // this construction looks strange, but without going through the
937 // address of fi, GCC would not cast fi to the base class of type
938 // BaseIterator but tries to go through constructing a new
939 // BaseIterator with an Accessor.
940  BaseIterator (*(BaseIterator *)(&fi)),
941  predicate (fi.predicate->clone ())
942 {}
943 
944 
945 
946 template <typename BaseIterator>
947 inline
950 {
951  delete predicate;
952  predicate = 0;
953 }
954 
955 
956 
957 template <typename BaseIterator>
958 inline
962 {
963  // Using equivalent code to the one for 'operator=(const BaseIterator &bi)'
964  // below, some compiler would not cast fi to the base class of type
965  // BaseIterator but try to go through constructing a new Accessor from fi
966  // which fails. Hence, we just use an explicit upcast and call the above-
967  // mentioned method.
968  const BaseIterator &bi = fi;
969  return operator = (bi);
970 }
971 
972 
973 
974 template <typename BaseIterator>
975 inline
978 operator = (const BaseIterator &bi)
979 {
980  Assert ((bi.state() != IteratorState::valid) || (*predicate)(bi),
981  ExcInvalidElement(bi));
982  BaseIterator::operator = (bi);
983  return *this;
984 }
985 
986 
987 
988 template <typename BaseIterator>
989 inline
992 set_to_next_positive (const BaseIterator &bi)
993 {
994  BaseIterator::operator = (bi);
995  while ((this->state() == IteratorState::valid) &&
996  ( ! (*predicate)(*this)))
997  BaseIterator::operator++ ();
998 
999  return *this;
1000 }
1001 
1002 
1003 
1004 template <typename BaseIterator>
1005 inline
1008 set_to_previous_positive (const BaseIterator &bi)
1009 {
1010  BaseIterator::operator = (bi);
1011  while ((this->state() == IteratorState::valid) &&
1012  ( ! (*predicate)(*this)))
1013  BaseIterator::operator-- ();
1014 
1015  return *this;
1016 }
1017 
1018 
1019 
1020 template <typename BaseIterator>
1021 inline
1022 bool
1025 {
1026  return (static_cast<const BaseIterator &>(*this)
1027  ==
1028  static_cast<const BaseIterator &>(fi));
1029 }
1030 
1031 
1032 
1033 template <typename BaseIterator>
1034 inline
1035 bool
1038 {
1039  return (static_cast<const BaseIterator &>(*this)
1040  !=
1041  static_cast<const BaseIterator &>(fi));
1042 }
1043 
1044 
1045 
1046 template <typename BaseIterator>
1047 inline
1048 bool
1051 {
1052  return (static_cast<const BaseIterator &>(*this)
1053  <
1054  static_cast<const BaseIterator &>(fi));
1055 }
1056 
1057 
1058 
1059 
1060 template <typename BaseIterator>
1061 inline
1062 bool
1064 operator == (const BaseIterator &bi) const
1065 {
1066  return (static_cast<const BaseIterator &>(*this) == bi);
1067 }
1068 
1069 
1070 
1071 template <typename BaseIterator>
1072 inline
1073 bool
1075 operator != (const BaseIterator &bi) const
1076 {
1077  return (static_cast<const BaseIterator &>(*this) != bi);
1078 }
1079 
1080 
1081 
1082 template <typename BaseIterator>
1083 inline
1084 bool
1086 operator < (const BaseIterator &bi) const
1087 {
1088  return (static_cast<const BaseIterator &>(*this) < bi);
1089 }
1090 
1091 
1092 template <typename BaseIterator>
1093 inline
1097 {
1098  if (this->state() == IteratorState::valid)
1099  do
1100  BaseIterator::operator++ ();
1101  while ((this->state() == IteratorState::valid) &&
1102  !(*predicate) (*this));
1103  return *this;
1104 }
1105 
1106 
1107 
1108 template <typename BaseIterator>
1109 inline
1113 {
1114  const FilteredIterator old_state = *this;
1115 
1116  if (this->state() == IteratorState::valid)
1117  do
1118  BaseIterator::operator++ ();
1119  while ((this->state() == IteratorState::valid) &&
1120  !(*predicate) (*this));
1121  return old_state;
1122 }
1123 
1124 
1125 
1126 
1127 template <typename BaseIterator>
1128 inline
1132 {
1133  if (this->state() == IteratorState::valid)
1134  do
1135  BaseIterator::operator-- ();
1136  while ((this->state() == IteratorState::valid) &&
1137  !(*predicate) (*this));
1138  return *this;
1139 }
1140 
1141 
1142 
1143 template <typename BaseIterator>
1144 inline
1148 {
1149  const FilteredIterator old_state = *this;
1150 
1151  if (this->state() == IteratorState::valid)
1152  do
1153  BaseIterator::operator-- ();
1154  while ((this->state() == IteratorState::valid) &&
1155  !(*predicate) (*this));
1156  return old_state;
1157 }
1158 
1159 
1160 
1161 template <typename BaseIterator>
1162 template <typename Predicate>
1163 inline
1165 PredicateTemplate (const Predicate &predicate)
1166  :
1167  predicate (predicate)
1168 {}
1169 
1170 
1171 
1172 template <typename BaseIterator>
1173 template <typename Predicate>
1174 bool
1176 operator () (const BaseIterator &bi) const
1177 {
1178  return predicate(bi);
1179 }
1180 
1181 
1182 
1183 template <typename BaseIterator>
1184 template <typename Predicate>
1187 clone () const
1188 {
1189  return new PredicateTemplate (predicate);
1190 }
1191 
1192 
1193 
1194 namespace IteratorFilters
1195 {
1196 
1197 // ---------------- IteratorFilters::Active ---------
1198 
1199  template <class Iterator>
1200  inline
1201  bool
1202  Active::operator () (const Iterator &i) const
1203  {
1204  return (i->active());
1205  }
1206 
1207 
1208 // ---------------- IteratorFilters::UserFlagSet ---------
1209 
1210  template <class Iterator>
1211  inline
1212  bool
1213  UserFlagSet::operator () (const Iterator &i) const
1214  {
1215  return (i->user_flag_set());
1216  }
1217 
1218 
1219 // ---------------- IteratorFilters::UserFlagNotSet ---------
1220 
1221  template <class Iterator>
1222  inline
1223  bool
1224  UserFlagNotSet::operator () (const Iterator &i) const
1225  {
1226  return (! i->user_flag_set());
1227  }
1228 
1229 
1230 // ---------------- IteratorFilters::LevelEqualTo ---------
1231  inline
1232  LevelEqualTo::LevelEqualTo (const unsigned int level)
1233  :
1234  level (level)
1235  {}
1236 
1237 
1238 
1239  template <class Iterator>
1240  inline
1241  bool
1242  LevelEqualTo::operator () (const Iterator &i) const
1243  {
1244  return (static_cast<unsigned int>(i->level()) == level);
1245  }
1246 
1247 
1248 
1249 // ---------------- IteratorFilters::SubdomainEqualTo ---------
1250  inline
1252  :
1253  subdomain_id (subdomain_id)
1254  {}
1255 
1256 
1257 
1258  template <class Iterator>
1259  inline
1260  bool
1261  SubdomainEqualTo::operator () (const Iterator &i) const
1262  {
1263  return (i->subdomain_id() == subdomain_id);
1264  }
1265 
1266 
1267 
1268 // ---------------- IteratorFilters::LocallyOwnedCell ---------
1269 
1270  template <class Iterator>
1271  inline
1272  bool
1273  LocallyOwnedCell::operator () (const Iterator &i) const
1274  {
1275  return (i->is_locally_owned());
1276  }
1277 
1278 
1279 // ---------------- IteratorFilters::LocallyOwnedLevelCell ---------
1280 
1281  template <class Iterator>
1282  inline
1283  bool
1284  LocallyOwnedLevelCell::operator () (const Iterator &i) const
1285  {
1286  return (i->is_locally_owned_on_level());
1287  }
1288 
1289 
1290 
1291 // ---------------- IteratorFilters::MaterialIdEqualTo ---------
1292  inline
1294  const bool only_locally_owned)
1295  :
1296  // Note: matrial_ids is a const member and has to be populated with a
1297  // constructor. Unfortunately, C++98/03 does not allow the use of an
1298  // initializer list. Therefore, treat material_id as an array of one
1299  // element.
1300  // This is well defined according to [expr.add].4 (ISO 14882).
1301  material_ids (&material_id, &material_id+1),
1302  only_locally_owned (only_locally_owned)
1303  {}
1304 
1305 
1306 
1307  inline
1308  MaterialIdEqualTo::MaterialIdEqualTo (const std::set<types::material_id> material_ids,
1309  const bool only_locally_owned)
1310  :
1311  material_ids (material_ids),
1312  only_locally_owned (only_locally_owned)
1313  {}
1314 
1315 
1316 
1317  template <class Iterator>
1318  inline
1319  bool
1320  MaterialIdEqualTo::operator () (const Iterator &i) const
1321  {
1322  return only_locally_owned == true ?
1323  (material_ids.find(i->material_id()) != material_ids.end() && i->is_locally_owned()):
1324  material_ids.find(i->material_id()) != material_ids.end();
1325  }
1326 
1327 
1328 
1329 // ---------------- IteratorFilters::ActiveFEIndexEqualTo ---------
1330  inline
1331  ActiveFEIndexEqualTo::ActiveFEIndexEqualTo (const unsigned int active_fe_index,
1332  const bool only_locally_owned)
1333  :
1334  // Note: active_fe_indices is a const member and has to be populated
1335  // with a constructor. Unfortunately, C++98/03 does not allow the use
1336  // of an initializer list. Therefore, treat active_fe_index as an array
1337  // of one element.
1338  // This is well defined according to [expr.add].4 (ISO 14882).
1339  active_fe_indices (&active_fe_index, &active_fe_index+1),
1340  only_locally_owned (only_locally_owned)
1341  {}
1342 
1343 
1344 
1345  inline
1346  ActiveFEIndexEqualTo::ActiveFEIndexEqualTo (const std::set<unsigned int> active_fe_indices,
1347  const bool only_locally_owned)
1348  :
1349  active_fe_indices (active_fe_indices),
1350  only_locally_owned (only_locally_owned)
1351  {}
1352 
1353 
1354 
1355  template <class Iterator>
1356  inline
1357  bool
1358  ActiveFEIndexEqualTo::operator () (const Iterator &i) const
1359  {
1360  return only_locally_owned == true ?
1361  (active_fe_indices.find(i->active_fe_index()) != active_fe_indices.end() && i->is_locally_owned()):
1362  active_fe_indices.find(i->active_fe_index()) != active_fe_indices.end();
1363  }
1364 
1365 
1366 
1367 // ---------------- IteratorFilters::AtBoundary ---------
1368 
1369  template <class Iterator>
1370  inline
1371  bool
1372  AtBoundary::operator () (const Iterator &i) const
1373  {
1374  return (i->at_boundary());
1375  }
1376 }
1377 
1378 
1379 DEAL_II_NAMESPACE_CLOSE
1380 
1381 /*------------------------- filtered_iterator.h ------------------------*/
1382 #endif
1383 /*------------------------- filtered_iterator.h ------------------------*/
1384 
1385 
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
unsigned char material_id
Definition: types.h:130
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const
STL namespace.
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
FilteredIterator & operator=(const FilteredIterator &fi)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:564
virtual PredicateBase * clone() const
#define Assert(cond, exc)
Definition: exceptions.h:313
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const
bool operator!=(const FilteredIterator &fi) const
virtual bool operator()(const BaseIterator &bi) const =0
unsigned int subdomain_id
Definition: types.h:42
MaterialIdEqualTo(const types::material_id material_id, const bool only_locally_owned=false)
bool operator()(const Iterator &i) const
LevelEqualTo(const unsigned int level)
const std::set< unsigned int > active_fe_indices
BaseIterator::AccessorType AccessorType
FilteredIterator & set_to_next_positive(const BaseIterator &bi)
SubdomainEqualTo(const types::subdomain_id subdomain_id)
virtual PredicateBase * clone() const =0
static ::ExceptionBase & ExcInvalidElement(BaseIterator arg1)
bool operator()(const Iterator &i) const
PredicateTemplate(const Predicate &predicate)
ActiveFEIndexEqualTo(const unsigned int active_fe_index, const bool only_locally_owned=false)
virtual bool operator()(const BaseIterator &bi) const
Iterator points to a valid object.
const PredicateBase * predicate
FilteredIterator & set_to_previous_positive(const BaseIterator &bi)
bool operator<(const FilteredIterator &fi) const
IteratorRange< typename internal::FilteredIterator::NestFilteredIterators< BaseIterator, std::tuple< Predicate, Targs... > >::type > filter_iterators(IteratorRange< BaseIterator > i, const Predicate &p, const Targs... args)
FilteredIterator< BaseIterator > make_filtered_iterator(const BaseIterator &i, const Predicate &p)
bool operator()(const Iterator &i) const