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