LIBINT  2.1.0-stable
entity.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_entity_h_
21 #define _libint2_src_bin_libint_entity_h_
22 
23 #include <string>
24 #include <sstream>
25 #include <dgvertex.h>
26 #include <class_registry.h>
27 
28 namespace libint2 {
29 
33  namespace EntityTypes {
34  typedef enum {fp, integer} EntityTypeEnum;
35 
36  template <unsigned int TypeIndex>
37  struct EntityType {
38  static unsigned int type2int() {
39  return TypeIndex;
40  }
41  };
42 
43  typedef EntityType<fp> FP;
44  typedef EntityType<integer> Int;
45 
46  static const unsigned int ntypes = 2;
47  };
48 
50  template <typename T, typename U>
51  struct ProductType;
52  template <> struct ProductType<int,int> { typedef int result; };
53  template <> struct ProductType<int,double> { typedef double result; };
54  template <> struct ProductType<double,int> { typedef double result; };
55  template <> struct ProductType<double,double> { typedef double result; };
56  template <> struct ProductType<EntityTypes::Int,int> { typedef EntityTypes::Int result; };
57  template <> struct ProductType<EntityTypes::Int,double> { typedef EntityTypes::FP result; };
58  template <> struct ProductType<EntityTypes::FP,int> { typedef EntityTypes::FP result; };
59  template <> struct ProductType<EntityTypes::FP,double> { typedef EntityTypes::FP result; };
60  template <> struct ProductType<int,EntityTypes::Int> { typedef EntityTypes::Int result; };
61  template <> struct ProductType<double,EntityTypes::Int> { typedef EntityTypes::FP result; };
62  template <> struct ProductType<int,EntityTypes::FP> { typedef EntityTypes::FP result; };
63  template <> struct ProductType<double,EntityTypes::FP> { typedef EntityTypes::FP result; };
64  template <> struct ProductType<EntityTypes::Int,EntityTypes::Int> { typedef EntityTypes::Int result; };
65  template <> struct ProductType<EntityTypes::Int,EntityTypes::FP> { typedef EntityTypes::FP result; };
66  template <> struct ProductType<EntityTypes::FP,EntityTypes::Int> { typedef EntityTypes::FP result; };
67  template <> struct ProductType<EntityTypes::FP,EntityTypes::FP> { typedef EntityTypes::FP result; };
68 
70  template <typename T>
71  std::string to_string(const T& x) {
72  std::ostringstream oss; oss << x; return oss.str();
73  }
74 
78  class Entity
79  {
80  public:
81  virtual ~Entity() {}
83  const std::string& id() const { return id_; }
84 
85  protected:
86  Entity(const std::string& id) : id_(id) {}
87 
88  private:
90  std::string id_;
91 
92  };
93 
98  template <class T>
99  class RTimeEntity :
100  public Entity,
101  public DGVertex
102  {
103  public:
104  typedef typename DGVertex::KeyType key_type;
105 
106  RTimeEntity(const std::string& id, bool p = true) :
107  Entity(id), DGVertex(ClassInfo<RTimeEntity>::Instance().id()), precomputed_(p)
108  {
109  FNVStringHash SH;
110  key_ = KeyTypes::cast(SH.hash(id));
111 #if DEBUG
112 std::cout << "Allocated RTimeEntity id = " << this->id() << std::endl;
113 #endif
114  }
115 
116  virtual ~RTimeEntity()
117  {
118 #if DEBUG
119  std::cout << "Deallocated RTimeEntity id = " << this->id() << std::endl;
120 #endif
121  }
122 
124  unsigned int size() const { return 1; }
125 
127  bool equiv(const SafePtr<DGVertex>& a) const
128  {
129  if (a->typeid_ == typeid_) {
130 #if USE_INT_KEY_TO_COMPARE
131  return key() == a->key() && label() == a->label();
132 #else
133  SafePtr<RTimeEntity> a_cast = static_pointer_cast<RTimeEntity,DGVertex>(a);
134  return id() == a_cast->id();
135 #endif
136  }
137  else
138  return false;
139  }
140 
142  const std::string& label() const
143  {
144  return Entity::id();
145  }
147  const std::string& id() const
148  {
149  return label();
150  }
152  std::string description() const
153  {
154  ostringstream os;
155  os << "RTimeEntity: " << id();
156  const std::string descr = os.str();
157  return descr;
158  }
160  typename DGVertex::KeyReturnType key() const {
161  return key_;
162  }
163 
164  private:
166  bool this_precomputed() const
167  {
168  return precomputed_;
169  }
170 
171  key_type key_;
175  bool precomputed_;
176  };
177 
182  template <class T>
183  class CTimeEntity :
184  public Entity,
185  public DGVertex
186  {
187  public:
188  CTimeEntity(const T& val) :
189  Entity(to_string(val)), DGVertex(ClassInfo<CTimeEntity>::Instance().id()), value_(val)
190  {
191 #if DEBUG
192  std::cout << "Allocated CTimeEntity id = " << this->id() << " value = " << value() << std::endl;
193 #endif
194  }
195 
196  virtual ~CTimeEntity()
197  {
198 #if DEBUG
199  std::cout << "Deallocated CTimeEntity id = " << this->id() << " value = " << value() << std::endl;
200 #endif
201  }
202 
204  unsigned int size() const { return 1; }
205 
207  bool equiv(const SafePtr<DGVertex>& a) const
208  {
209  if (a->typeid_ == typeid_) {
210 #if USE_INT_KEY_TO_COMPARE
211  return key() == a->key();
212 #else
213  SafePtr<CTimeEntity> a_cast = static_pointer_cast<CTimeEntity,DGVertex>(a);
214  return id() == a_cast->id();
215 #endif
216  }
217  else
218  return false;
219  }
220 
222  const std::string& label() const
223  {
224  return Entity::id();
225  }
227  const std::string& id() const
228  {
229  return label();
230  }
232  std::string description() const
233  {
234  ostringstream os;
235  os << "CTimeEntity: " << id();
236  const std::string descr = os.str();
237  return descr;
238  }
239 
241  typename KeyTraits<T>::ReturnType value() const { return value_; }
242 
244  typename DGVertex::KeyReturnType key() const {
245  if (std::is_floating_point<T>::value) {
246  if (not std::is_same<T,double>::value)
247  throw std::runtime_error("CTimeEntity<Real> only supported when Real==double");
248  return static_cast<typename DGVertex::KeyReturnType>(*reinterpret_cast<const unsigned long*>(&value_));
249  }
250  else
251  return static_cast<typename DGVertex::KeyReturnType>(value());
252  }
253 
254  private:
255  T value_;
256 
258  bool this_precomputed() const
259  {
260  return true;
261  }
262 
263  };
264 
265 
269 // template <typename T>
270 // SafePtr<Entity>
271 // operator*(const SafePtr<Entity>& A, const SafePtr< CTimeEntity<T> >& B);
272 
275  template <typename T, typename U>
276  SafePtr< CTimeEntity< typename ProductType<T,U>::result > >
277  operator*(const SafePtr< CTimeEntity<T> >& A, const SafePtr< CTimeEntity<U> >& B)
278  {
280  return SafePtr<prodtype>(new prodtype(A->value()*B->value()));
281  }
282 
285  template <typename T, typename U>
286  SafePtr< RTimeEntity< typename ProductType<T,U>::result > >
287  operator*(const SafePtr< RTimeEntity<T> >& A, const SafePtr< CTimeEntity<U> >& B)
288  {
290  ostringstream oss;
291  oss << A->id() << "*" << B->id();
292  // TODO this should be false, but the logic of DirectedGraph construction depends on this being true
293  const bool not_precomputed = true;
294  return SafePtr<prodtype>(new prodtype(oss.str(), not_precomputed));
295  }
296  // TODO should be possible to enable this, but this creates RTimeEntities that should not be precomputed, see the comment above
297 #if 0
298 
300  template <typename T, typename U>
301  SafePtr< RTimeEntity< typename ProductType<T,U>::result > >
302  operator*(const SafePtr< CTimeEntity<U> >& B, const SafePtr< RTimeEntity<T> >& A)
303  {
304  return A * B;
305  }
306 #endif
307 
308 };
309 
310 #endif
311 
bool equiv(const SafePtr< DGVertex > &a) const
Implementation of DGVertex::equiv()
Definition: entity.h:127
bool equiv(const SafePtr< DGVertex > &a) const
Implementation of DGVertex::equiv()
Definition: entity.h:207
KeyTypes::InstanceID KeyType
DGVertex provides function key() which computes key of type KeyType and returns it using KeyReturnTyp...
Definition: dgvertex.h:60
CTimeEntity is an Entity of type T that exists at compile-time of the generated code (hence has a val...
Definition: entity.h:183
unsigned int size() const
Implementation of DGVertex::size()
Definition: entity.h:124
Definition: entity.h:37
const std::string & id() const
Implementation of DGVertex::id()
Definition: entity.h:147
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:23
const std::string & id() const
Implementation of DGVertex::id()
Definition: entity.h:227
const std::string & label() const
Implementation of DGVertex::label()
Definition: entity.h:222
SafePtr< CTimeEntity< typename ProductType< T, U >::result > > operator*(const SafePtr< CTimeEntity< T > > &A, const SafePtr< CTimeEntity< U > > &B)
Creates product A*B.
Definition: entity.h:277
const std::string & id() const
Return id string.
Definition: entity.h:83
Product of 2 types.
Definition: entity.h:51
This is a vertex of a Directed Graph (DG)
Definition: dgvertex.h:42
std::string description() const
Implementation of DGVertex::description()
Definition: entity.h:232
KeyTraits< T >::ReturnType value() const
returns the value
Definition: entity.h:241
FNVStringHash uses Fowler/Noll/Vo algorithm to hash a char string to a 64-bit integer.
Definition: hashable.h:87
DGVertex::KeyReturnType key() const
Implements Hashable::key()
Definition: entity.h:160
RTimeEntity is an Entity of type T that exists at runtime of the generated code (hence has no value k...
Definition: entity.h:99
Entity is a base class for all objects that exist at compile or runtime of the generated code...
Definition: entity.h:78
std::string to_string(const T &x)
Converts x to its string representation.
Definition: entity.h:71
std::string description() const
Implementation of DGVertex::description()
Definition: entity.h:152
const std::string & label() const
Implementation of DGVertex::label()
Definition: entity.h:142
Objects of this type provide limited information about the class at runtime.
Definition: class_registry.h:43
unsigned int size() const
Implementation of DGVertex::size()
Definition: entity.h:204
virtual const std::string & id() const =0
id() returns a very short label of DGVertex which is (almost) guaranteed to be a symbol (e...
DGVertex::KeyReturnType key() const
Implements Hashable::key()
Definition: entity.h:244
LIBINT2_UINT_LEAST64 hash(const std::string &S)
Returns 64-bit integer hash of S.
Definition: hashable.h:110