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