LIBINT  2.1.0-stable
singl_stack.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 #ifndef _libint2_src_bin_libint_singlstack_h_
21 #define _libint2_src_bin_libint_singlstack_h_
22 
23 #include <map>
24 #include <iostream>
25 #include <smart_ptr.h>
26 #include <key.h>
27 #include <hashable.h>
28 #include <purgeable.h>
29 
30 namespace libint2 {
31 
32  class RecurrenceRelation;
33 
41  template <class T, class KeyType>
42  class SingletonStack : public PurgeableStack<T>
43  {
44  public:
45  typedef KeyType key_type;
46  typedef SafePtr<T> data_type;
49  typedef std::pair<InstanceID,SafePtr<T> > value_type;
50  typedef std::map<key_type,value_type> map_type;
52  typedef typename map_type::iterator iter_type;
54  typedef typename map_type::const_iterator citer_type;
56  typedef typename KeyTraits<key_type>::ReturnType key_return_type;
58  typedef key_return_type (T::* HashingFunction)() const;
61 
62 
65  map_(), callback_(callback), next_instance_(0)
66  {
67  if (PurgingPolicy::purgeable()) { // if this stack contains objects that can be purged, add to the registry
68  PurgeableStacks::Instance()->register_stack(this);
69  }
70  }
71 
72  virtual ~SingletonStack() {}
73 
79  const value_type& find(const SafePtr<T>& obj) {
80  key_type key = ((obj.get())->*callback_)();
81 
82  typedef typename map_type::iterator miter;
83  miter pos = map_.find(key);
84  if (pos != map_.end()) {
85 #if DEBUG || LOCAL_DEBUG
86  std::cout << "SingletonStack::find -- " << obj->label() << " already found" << std::endl;
87 #endif
88  return (*pos).second;
89  }
90  else {
91  value_type result(next_instance_++,obj);
92  map_[key] = result;
93 #if DEBUG || LOCAL_DEBUG
94  std::cout << "SingletonStack::find -- " << obj->label() << " is new (instid_ = " << next_instance_-1 << ")" << std::endl;
95 #endif
96  return map_[key];
97  }
98  }
99 
104  const value_type& find(const key_type& key) {
105  static value_type null_value(make_pair(InstanceID(0),SafePtr<T>()));
106  typedef typename map_type::iterator miter;
107  miter pos = map_.find(key);
108  if (pos != map_.end()) {
109  return (*pos).second;
110  }
111  else {
112  return null_value;
113  }
114  }
115 
120  const value_type& find_hashed(const InstanceID& hashed_key) const {
121  static value_type null_value(make_pair(InstanceID(0),SafePtr<T>()));
122  for(auto& i: map_) {
123  if (i.second.first == hashed_key)
124  return i.second;
125  }
126  return null_value;
127  }
128 
131  void remove(const SafePtr<T>& obj) {
132  key_type key = ((obj.get())->*callback_)();
133 
134  typedef typename map_type::iterator miter;
135  miter pos = map_.find(key);
136  if (pos != map_.end()) {
137  map_.erase(pos);
138 #if DEBUG || LOCAL_DEBUG
139  std::cout << "Removed from stack " << obj->label() << std::endl;
140 #endif
141  }
142  }
143 
145  citer_type begin() const { return map_.begin(); }
147  citer_type end() const { return map_.end(); }
148 
149  // Implementation of PurgeableStack::purge()
150  virtual void purge() {
151  for(iter_type i = map_.begin(); i!=map_.end();) {
152  const T* v = i->second.second.get();
153  if (PurgingPolicy::purge(v))
154  // map::erase invalidates the iterator, increment it beforehand
155  map_.erase(i++);
156  else
157  ++i;
158  }
159  }
160 
161  private:
162  map_type map_;
163  HashingFunction callback_;
164  InstanceID next_instance_;
165  };
166 
167 };
168 
169 #endif
mpz_class InstanceID
some classes need to have distinct instances to have unique InstanceID&#39;s, e.g. generalized Singletons...
Definition: key.h:80
SingletonStack<T,KeyType> helps to implement Singleton-like objects of type T.
Definition: singl_stack.h:42
citer_type end() const
Returns iterator to the end of the stack.
Definition: singl_stack.h:147
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:23
KeyTypes::InstanceID InstanceID
Specifies type for the instance index variables.
Definition: singl_stack.h:48
map_type::iterator iter_type
use iter_type objects to iterate over the stack
Definition: singl_stack.h:52
PurgeableStack< T >::PurgingPolicy PurgingPolicy
PurgingPolicy determines whether and which objects on this stack are obsolete and can be removed...
Definition: singl_stack.h:60
const value_type & find(const SafePtr< T > &obj)
Returns the pointer to the unique instance of object obj.
Definition: singl_stack.h:79
key_return_type(T::* HashingFunction)() const
Specifies the type of callback which computes hashes.
Definition: singl_stack.h:58
map_type::const_iterator citer_type
const version of iter_type
Definition: singl_stack.h:54
const value_type & find_hashed(const InstanceID &hashed_key) const
Returns the pointer to the unique instance of object corresponding to the hashed_key.
Definition: singl_stack.h:120
PurgeableStack is an AbstractPurgeableStack that contains objects of type T.
Definition: purgeable.h:78
const value_type & find(const key_type &key)
Returns the pointer to the unique instance of object corresponding to key.
Definition: singl_stack.h:104
SingletonStack(HashingFunction callback)
callback to compute hash values is the only parameter
Definition: singl_stack.h:64
citer_type begin() const
Returns iterator to the beginning of the stack.
Definition: singl_stack.h:145
KeyTraits< key_type >::ReturnType key_return_type
hashing function returns keys as key_return_type
Definition: singl_stack.h:56