LIBINT  2.6.0
iter.h
1 /*
2  * Copyright (C) 2004-2019 Edward F. Valeev
3  *
4  * This file is part of Libint.
5  *
6  * Libint is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Libint is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Libint. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include <vector>
22 #include <smart_ptr.h>
23 #include <policy.h>
24 #include <polyconstr.h>
25 #include <exception.h>
26 
27 #ifndef _libint2_src_bin_libint_iter_h_
28 #define _libint2_src_bin_libint_iter_h_
29 
30 // gcc 3.4 doesn't seem to allow
31 //#define ALLOW_PARTIALLY_SPECIALIZED_NESTED_TEMPLATES
32 
33 
34 using namespace std;
35 
36 namespace libint2 {
37 
38  struct DummyIterator;
39 
45  class SubIterator {
46 
47  public:
49  virtual unsigned int num_iter() const =0;
51  virtual void init() =0;
53  virtual SubIterator& operator++() =0;
55  virtual operator int() const =0;
59  virtual const ConstructablePolymorphically& pelem() const;
60  virtual ~SubIterator();
61 
62  protected:
63  SubIterator();
64 
65  private:
66  //SubIterator operator++(int);
67  };
68 
73  template <class T, template <class> class Tr = Policy > class SubIteratorBase : public SubIterator {
74 
75  public:
76  typedef typename T::iter_type iter_type;
77  typedef Tr<T> TPolicy;
78  typedef typename TPolicy::obj_stype tref;
79  typedef typename TPolicy::subobj_stype iref;
82  SubIteratorBase(const tref&);
83  virtual ~SubIteratorBase();
84 
86  const iref& elem() const;
88  cp_rettype pelem() const;
89 
91  unsigned int num_iter() const;
93  void init();
95  SubIterator& operator++();
97  operator int() const;
98 
99  protected:
100  const tref obj_;
101  vector<iref> subobj_;
102 
103  private:
105  unsigned int iter_;
106 
107  // These templates are used as a trick to make possible "partial specialization
108  // of a template with multiple template params". Default implementations are not provided
109  // so user must provide specialization for the case X=T
110  template <class X> void init_subobj();
111  template <class X> void delete_subobj();
112  void init_subobj();
113  void delete_subobj();
114 
115  // implementation of pelem()
116  template <typename X, bool return_smart_ptr>
117  struct PElemImpl {
118  };
119  template <typename X>
120  struct PElemImpl<X,true> {
121  static cp_rettype pelem(const iref& elem) {
122  SafePtr<ConstructablePolymorphically> elem_cast = dynamic_pointer_cast<ConstructablePolymorphically,X>(elem);
123  return *(elem_cast.get());
124  }
125  };
126  template <typename X>
127  struct PElemImpl<X,false> {
128  static cp_rettype pelem(const iref& elem) {
129  return elem;
130  }
131  };
132 
133  };
134 
135  template <class T, template <class> class P>
136  SubIteratorBase<T,P>::SubIteratorBase(const tref& obj) :
137  obj_(obj), subobj_(0), iter_(0)
138  {
139 #ifdef ALLOW_PARTIALLY_SPECIALIZED_NESTED_TEMPLATES
140  init_subobj<T>();
141 #else
142  init_subobj();
143 #endif
144  }
145 
146  template <class T, template <class> class P>
147  SubIteratorBase<T,P>::~SubIteratorBase()
148  {
149 #ifdef ALLOW_PARTIALLY_SPECIALIZED_NESTED_TEMPLATES
150  delete_subobj<T>();
151 #else
152  delete_subobj();
153 #endif
154  }
155 
156  template <class T, template <class> class P>
157  unsigned int
159  {
160  return subobj_.size();
161  }
162 
163  template <class T, template <class> class P>
164  const typename SubIteratorBase<T,P>::iref&
166  {
167  return subobj_.at(iter_);
168  }
169 
170  template <class T, template <class> class P>
173  {
174  return PElemImpl<iter_type,detail::IsSafePtr<iref>::result>::pelem(elem());
175  }
176 
177 #if 0
178  template <class T, template <class> class P>
179  const SafePtr<ConstructablePolymorphically>
181  {
182  return dynamic_pointer_cast<ConstructablePolymorphically,iter_type>(elem());
183  }
184 #endif
185 
186  template <class T, template <class> class P>
187  void
189  {
190  iter_ = 0;
191  }
192 
193  template <class T, template <class> class P>
194  SubIterator&
196  {
197  ++iter_;
198  return *this;
199  }
200 
201  template <class T, template <class> class P>
203  {
204  return (iter_ < num_iter()) ? 1 : 0;
205  }
206 
207  template <class T, template <class> class P>
208  void
210  {
211  P<T>::init_subobj(obj_,subobj_);
212  }
213 
214  template <class T, template <class> class P>
215  void
216  SubIteratorBase<T,P>::delete_subobj()
217  {
218  P<T>::dealloc_subobj(subobj_);
219  }
220 
221 };
222 
223 #endif
unsigned int num_iter() const
Returns a number of iterations (number of elements in a set over which to iterate).
Definition: iter.h:158
ConstructablePolymorphically is a base for all objects which can be constructed using a SafePtr to a ...
Definition: polyconstr.h:31
const ConstructablePolymorphically & cp_rettype
Return reference to ConstructablePolymorphically as object of this type.
Definition: iter.h:81
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
void init()
Initializes the iterator.
Definition: iter.h:188
SubIteratorBase<T> provides a base class for a sub-iterator class for T.
Definition: iter.h:73
SubIterator & operator++()
Iterates to the next element. Only prefix form is provided.
Definition: iter.h:195
Iterator provides a base class for all object iterator classes.
Definition: iter.h:45
const iref & elem() const
Returns current element.
Definition: iter.h:165
cp_rettype pelem() const
Returns current element. Implements SubIterator's pelem().
Definition: iter.h:172