Reference documentation for deal.II version 9.0.0
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 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/std_cxx14/memory.h>
21 #include <deal.II/base/config.h>
22 #include <deal.II/base/exceptions.h>
23 #include <deal.II/base/iterator_range.h>
24 #include <deal.II/grid/tria_iterator_base.h>
25 
26 #include <set>
27 #include <tuple>
28 
29 DEAL_II_NAMESPACE_OPEN
30 
31 
48 namespace IteratorFilters
49 {
56  class Active
57  {
58  public:
63  template <class Iterator>
64  bool operator () (const Iterator &i) const;
65  };
66 
76  {
77  public:
82  template <class Iterator>
83  bool operator () (const Iterator &i) const;
84  };
85 
86 
95  {
96  public:
101  template <class Iterator>
102  bool operator () (const Iterator &i) const;
103  };
104 
105 
114  {
115  public:
120  LevelEqualTo (const unsigned int level);
121 
127  template <class Iterator>
128  bool operator () (const Iterator &i) const;
129 
130  protected:
134  const unsigned int level;
135  };
136 
137 
138 
148  {
149  public:
155 
161  template <class Iterator>
162  bool operator () (const Iterator &i) const;
163 
164  protected:
169  };
170 
171 
172 
185  {
186  public:
190  template <class Iterator>
191  bool operator () (const Iterator &i) const;
192  };
193 
194 
195 
203  {
204  public:
209  template <class Iterator>
210  bool operator () (const Iterator &i) const;
211  };
212 
213 
224  {
225  public:
230  MaterialIdEqualTo (const types::material_id material_id,
231  const bool only_locally_owned = false);
232 
238  MaterialIdEqualTo (const std::set<types::material_id> &material_ids,
239  const bool only_locally_owned = false);
240 
246  template <class Iterator>
247  bool operator () (const Iterator &i) const;
248 
249  protected:
253  const std::set<types::material_id> material_ids;
257  const bool only_locally_owned;
258  };
259 
270  {
271  public:
276  ActiveFEIndexEqualTo (const unsigned int active_fe_index,
277  const bool only_locally_owned = false);
278 
284  ActiveFEIndexEqualTo (const std::set<unsigned int> &active_fe_indices,
285  const bool only_locally_owned = false);
286 
292  template <class Iterator>
293  bool operator () (const Iterator &i) const;
294 
295  protected:
299  const std::set<unsigned int> active_fe_indices;
303  const bool only_locally_owned;
304  };
305 
315  {
316  public:
320  template <class Iterator>
321  bool operator () (const Iterator &i) const;
322  };
323 }
324 
325 
511 template <typename BaseIterator>
512 class FilteredIterator : public BaseIterator
513 {
514 public:
518  typedef typename BaseIterator::AccessorType AccessorType;
519 
524  template <typename Predicate>
525  FilteredIterator (Predicate p);
526 
544  template <typename Predicate>
545  FilteredIterator (Predicate p,
546  const BaseIterator &bi);
547 
553 
558 
566 
572  FilteredIterator &operator = (const BaseIterator &fi);
573 
583  set_to_next_positive (const BaseIterator &bi);
584 
594  set_to_previous_positive (const BaseIterator &bi);
595 
602  bool operator == (const FilteredIterator &fi) const;
603 
610  bool operator == (const BaseIterator &fi) const;
611 
618  bool operator != (const FilteredIterator &fi) const;
619 
626  bool operator != (const BaseIterator &fi) const;
627 
634  bool operator < (const FilteredIterator &fi) const;
635 
642  bool operator < (const BaseIterator &fi) const;
643 
649 
655 
661 
667 
672  BaseIterator,
673  << "The element " << arg1
674  << " with which you want to compare or which you want to"
675  << " assign from is invalid since it does not satisfy the predicate.");
676 
677 private:
678 
689  {
690  public:
695  virtual ~PredicateBase () = default;
696 
701  virtual bool operator () (const BaseIterator &bi) const = 0;
702 
707  virtual std::unique_ptr<PredicateBase> clone () const = 0;
708  };
709 
710 
719  template <typename Predicate>
721  {
722  public:
726  PredicateTemplate (const Predicate &predicate);
727 
731  virtual bool operator () (const BaseIterator &bi) const override;
732 
737  virtual std::unique_ptr<PredicateBase> clone () const override;
738 
739  private:
743  const Predicate predicate;
744  };
745 
750  std::unique_ptr<const PredicateBase> predicate;
751 
752 };
753 
754 
755 
765 template <typename BaseIterator, typename Predicate>
767 make_filtered_iterator (const BaseIterator &i,
768  const Predicate &p)
769 {
771  fi.set_to_next_positive (i);
772  return fi;
773 }
774 
775 
776 
777 namespace internal
778 {
779  namespace FilteredIteratorImplementation
780  {
781  // The following classes create a nested sequence of
782  // FilteredIterator<FilteredIterator<...<BaseIterator>...>> with as many
783  // levels of FilteredIterator classes as there are elements in the TypeList
784  // if the latter is given as a std::tuple<Args...>.
785  template <typename BaseIterator, typename TypeList>
786  struct NestFilteredIterators;
787 
788  template <typename BaseIterator, typename Predicate>
789  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate> >
790  {
791  typedef ::FilteredIterator<BaseIterator> type;
792  };
793 
794  template <typename BaseIterator, typename Predicate, typename... Targs>
795  struct NestFilteredIterators<BaseIterator, std::tuple<Predicate, Targs...> >
796  {
797  typedef ::FilteredIterator<typename NestFilteredIterators<BaseIterator,
798  std::tuple<Targs...> >::type> type;
799  };
800  }
801 }
802 
803 
804 
836 template <typename BaseIterator, typename Predicate>
839  const Predicate &p)
840 {
842  FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
843 
844  return IteratorRange<FilteredIterator<BaseIterator> > (fi, fi_end);
845 }
846 
847 
848 
884 template <typename BaseIterator, typename Predicate, typename... Targs>
885 IteratorRange<typename internal::FilteredIteratorImplementation::
886 NestFilteredIterators<BaseIterator,std::tuple<Predicate, Targs...> >::type>
888  const Predicate &p,
889  const Targs... args)
890 {
891  // Recursively create filtered iterators, one predicate at a time
892  auto fi = filter_iterators(i,p);
893  return filter_iterators(fi, args...);
894 }
895 
896 
897 /* ------------------ Inline functions and templates ------------ */
898 
899 
900 template <typename BaseIterator>
901 template <typename Predicate>
902 inline
904 FilteredIterator (Predicate p)
905  :
906  predicate (new PredicateTemplate<Predicate>(p))
907 {}
908 
909 
910 
911 template <typename BaseIterator>
912 template <typename Predicate>
913 inline
915 FilteredIterator (Predicate p,
916  const BaseIterator &bi)
917  :
918  BaseIterator (bi),
919  predicate (new PredicateTemplate<Predicate>(p))
920 {
921  if ((this->state() == IteratorState::valid) &&
922  ! (*predicate) (*this))
924 }
925 
926 
927 
928 template <typename BaseIterator>
929 inline
932  :
933 // this construction looks strange, but without going through the
934 // address of fi, GCC would not cast fi to the base class of type
935 // BaseIterator but tries to go through constructing a new
936 // BaseIterator with an Accessor.
937  BaseIterator (*(BaseIterator *)(&fi)),
938  predicate (fi.predicate->clone ())
939 {}
940 
941 
942 
943 template <typename BaseIterator>
944 inline
947 {
948  predicate.reset();
949 }
950 
951 
952 
953 template <typename BaseIterator>
954 inline
958 {
959  // Using equivalent code to the one for 'operator=(const BaseIterator &bi)'
960  // below, some compiler would not cast fi to the base class of type
961  // BaseIterator but try to go through constructing a new Accessor from fi
962  // which fails. Hence, we just use an explicit upcast and call the above-
963  // mentioned method.
964  const BaseIterator &bi = fi;
965  return operator = (bi);
966 }
967 
968 
969 
970 template <typename BaseIterator>
971 inline
974 operator = (const BaseIterator &bi)
975 {
976  Assert ((bi.state() != IteratorState::valid) || (*predicate)(bi),
977  ExcInvalidElement(bi));
978  BaseIterator::operator = (bi);
979  return *this;
980 }
981 
982 
983 
984 template <typename BaseIterator>
985 inline
988 set_to_next_positive (const BaseIterator &bi)
989 {
990  BaseIterator::operator = (bi);
991  while ((this->state() == IteratorState::valid) &&
992  ( ! (*predicate)(*this)))
993  BaseIterator::operator++ ();
994 
995  return *this;
996 }
997 
998 
999 
1000 template <typename BaseIterator>
1001 inline
1004 set_to_previous_positive (const BaseIterator &bi)
1005 {
1006  BaseIterator::operator = (bi);
1007  while ((this->state() == IteratorState::valid) &&
1008  ( ! (*predicate)(*this)))
1009  BaseIterator::operator-- ();
1010 
1011  return *this;
1012 }
1013 
1014 
1015 
1016 template <typename BaseIterator>
1017 inline
1018 bool
1021 {
1022  return (static_cast<const BaseIterator &>(*this)
1023  ==
1024  static_cast<const BaseIterator &>(fi));
1025 }
1026 
1027 
1028 
1029 template <typename BaseIterator>
1030 inline
1031 bool
1034 {
1035  return (static_cast<const BaseIterator &>(*this)
1036  !=
1037  static_cast<const BaseIterator &>(fi));
1038 }
1039 
1040 
1041 
1042 template <typename BaseIterator>
1043 inline
1044 bool
1047 {
1048  return (static_cast<const BaseIterator &>(*this)
1049  <
1050  static_cast<const BaseIterator &>(fi));
1051 }
1052 
1053 
1054 
1055 
1056 template <typename BaseIterator>
1057 inline
1058 bool
1060 operator == (const BaseIterator &bi) const
1061 {
1062  return (static_cast<const BaseIterator &>(*this) == bi);
1063 }
1064 
1065 
1066 
1067 template <typename BaseIterator>
1068 inline
1069 bool
1071 operator != (const BaseIterator &bi) const
1072 {
1073  return (static_cast<const BaseIterator &>(*this) != bi);
1074 }
1075 
1076 
1077 
1078 template <typename BaseIterator>
1079 inline
1080 bool
1082 operator < (const BaseIterator &bi) const
1083 {
1084  return (static_cast<const BaseIterator &>(*this) < bi);
1085 }
1086 
1087 
1088 template <typename BaseIterator>
1089 inline
1093 {
1094  if (this->state() == IteratorState::valid)
1095  do
1096  BaseIterator::operator++ ();
1097  while ((this->state() == IteratorState::valid) &&
1098  !(*predicate) (*this));
1099  return *this;
1100 }
1101 
1102 
1103 
1104 template <typename BaseIterator>
1105 inline
1109 {
1110  const FilteredIterator old_state = *this;
1111 
1112  if (this->state() == IteratorState::valid)
1113  do
1114  BaseIterator::operator++ ();
1115  while ((this->state() == IteratorState::valid) &&
1116  !(*predicate) (*this));
1117  return old_state;
1118 }
1119 
1120 
1121 
1122 
1123 template <typename BaseIterator>
1124 inline
1128 {
1129  if (this->state() == IteratorState::valid)
1130  do
1131  BaseIterator::operator-- ();
1132  while ((this->state() == IteratorState::valid) &&
1133  !(*predicate) (*this));
1134  return *this;
1135 }
1136 
1137 
1138 
1139 template <typename BaseIterator>
1140 inline
1144 {
1145  const FilteredIterator old_state = *this;
1146 
1147  if (this->state() == IteratorState::valid)
1148  do
1149  BaseIterator::operator-- ();
1150  while ((this->state() == IteratorState::valid) &&
1151  !(*predicate) (*this));
1152  return old_state;
1153 }
1154 
1155 
1156 
1157 template <typename BaseIterator>
1158 template <typename Predicate>
1159 inline
1161 PredicateTemplate (const Predicate &predicate)
1162  :
1163  predicate (predicate)
1164 {}
1165 
1166 
1167 
1168 template <typename BaseIterator>
1169 template <typename Predicate>
1170 bool
1172 operator () (const BaseIterator &bi) const
1173 {
1174  return predicate(bi);
1175 }
1176 
1177 
1178 
1179 template <typename BaseIterator>
1180 template <typename Predicate>
1181 std::unique_ptr<typename FilteredIterator<BaseIterator>::PredicateBase>
1183 clone () const
1184 {
1185  return std_cxx14::make_unique<PredicateTemplate> (predicate);
1186 }
1187 
1188 
1189 
1190 namespace IteratorFilters
1191 {
1192 
1193 // ---------------- IteratorFilters::Active ---------
1194 
1195  template <class Iterator>
1196  inline
1197  bool
1198  Active::operator () (const Iterator &i) const
1199  {
1200  return (i->active());
1201  }
1202 
1203 
1204 // ---------------- IteratorFilters::UserFlagSet ---------
1205 
1206  template <class Iterator>
1207  inline
1208  bool
1209  UserFlagSet::operator () (const Iterator &i) const
1210  {
1211  return (i->user_flag_set());
1212  }
1213 
1214 
1215 // ---------------- IteratorFilters::UserFlagNotSet ---------
1216 
1217  template <class Iterator>
1218  inline
1219  bool
1220  UserFlagNotSet::operator () (const Iterator &i) const
1221  {
1222  return (! i->user_flag_set());
1223  }
1224 
1225 
1226 // ---------------- IteratorFilters::LevelEqualTo ---------
1227  inline
1228  LevelEqualTo::LevelEqualTo (const unsigned int level)
1229  :
1230  level (level)
1231  {}
1232 
1233 
1234 
1235  template <class Iterator>
1236  inline
1237  bool
1238  LevelEqualTo::operator () (const Iterator &i) const
1239  {
1240  return (static_cast<unsigned int>(i->level()) == level);
1241  }
1242 
1243 
1244 
1245 // ---------------- IteratorFilters::SubdomainEqualTo ---------
1246  inline
1248  :
1249  subdomain_id (subdomain_id)
1250  {}
1251 
1252 
1253 
1254  template <class Iterator>
1255  inline
1256  bool
1257  SubdomainEqualTo::operator () (const Iterator &i) const
1258  {
1259  return (i->subdomain_id() == subdomain_id);
1260  }
1261 
1262 
1263 
1264 // ---------------- IteratorFilters::LocallyOwnedCell ---------
1265 
1266  template <class Iterator>
1267  inline
1268  bool
1269  LocallyOwnedCell::operator () (const Iterator &i) const
1270  {
1271  return (i->is_locally_owned());
1272  }
1273 
1274 
1275 // ---------------- IteratorFilters::LocallyOwnedLevelCell ---------
1276 
1277  template <class Iterator>
1278  inline
1279  bool
1280  LocallyOwnedLevelCell::operator () (const Iterator &i) const
1281  {
1282  return (i->is_locally_owned_on_level());
1283  }
1284 
1285 
1286 
1287 // ---------------- IteratorFilters::MaterialIdEqualTo ---------
1288  inline
1290  const bool only_locally_owned)
1291  :
1292  material_ids {material_id},
1293  only_locally_owned (only_locally_owned)
1294  {}
1295 
1296 
1297 
1298  inline
1299  MaterialIdEqualTo::MaterialIdEqualTo (const std::set<types::material_id> &material_ids,
1300  const bool only_locally_owned)
1301  :
1302  material_ids (material_ids),
1303  only_locally_owned (only_locally_owned)
1304  {}
1305 
1306 
1307 
1308  template <class Iterator>
1309  inline
1310  bool
1311  MaterialIdEqualTo::operator () (const Iterator &i) const
1312  {
1313  return only_locally_owned == true ?
1314  (material_ids.find(i->material_id()) != material_ids.end() && i->is_locally_owned()):
1315  material_ids.find(i->material_id()) != material_ids.end();
1316  }
1317 
1318 
1319 
1320 // ---------------- IteratorFilters::ActiveFEIndexEqualTo ---------
1321  inline
1322  ActiveFEIndexEqualTo::ActiveFEIndexEqualTo (const unsigned int active_fe_index,
1323  const bool only_locally_owned)
1324  :
1325  active_fe_indices {active_fe_index},
1326  only_locally_owned (only_locally_owned)
1327  {}
1328 
1329 
1330 
1331  inline
1332  ActiveFEIndexEqualTo::ActiveFEIndexEqualTo (const std::set<unsigned int> &active_fe_indices,
1333  const bool only_locally_owned)
1334  :
1335  active_fe_indices (active_fe_indices),
1336  only_locally_owned (only_locally_owned)
1337  {}
1338 
1339 
1340 
1341  template <class Iterator>
1342  inline
1343  bool
1344  ActiveFEIndexEqualTo::operator () (const Iterator &i) const
1345  {
1346  return only_locally_owned == true ?
1347  (active_fe_indices.find(i->active_fe_index()) != active_fe_indices.end() && i->is_locally_owned()):
1348  active_fe_indices.find(i->active_fe_index()) != active_fe_indices.end();
1349  }
1350 
1351 
1352 
1353 // ---------------- IteratorFilters::AtBoundary ---------
1354 
1355  template <class Iterator>
1356  inline
1357  bool
1358  AtBoundary::operator () (const Iterator &i) const
1359  {
1360  return (i->at_boundary());
1361  }
1362 }
1363 
1364 
1365 DEAL_II_NAMESPACE_CLOSE
1366 
1367 /*------------------------- filtered_iterator.h ------------------------*/
1368 #endif
1369 /*------------------------- 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
bool operator()(const Iterator &i) const
STL namespace.
IteratorOverIterators end()
IteratorRange< FilteredIterator< BaseIterator > > filter_iterators(IteratorRange< BaseIterator > i, const Predicate &p)
virtual std::unique_ptr< PredicateBase > clone() const =0
unsigned int material_id
Definition: types.h:133
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:346
#define Assert(cond, exc)
Definition: exceptions.h:1142
bool operator()(const Iterator &i) const
bool operator()(const Iterator &i) const
virtual bool operator()(const BaseIterator &bi) const override
std::unique_ptr< const PredicateBase > predicate
bool operator!=(const FilteredIterator &fi) const
virtual ~PredicateBase()=default
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)
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)
Iterator points to a valid object.
FilteredIterator & set_to_previous_positive(const BaseIterator &bi)
bool operator<(const FilteredIterator &fi) const
virtual std::unique_ptr< PredicateBase > clone() const override
FilteredIterator< BaseIterator > make_filtered_iterator(const BaseIterator &i, const Predicate &p)
bool operator()(const Iterator &i) const