LIBINT  2.6.0
entity.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 #ifndef _libint2_src_bin_libint_entity_h_
22 #define _libint2_src_bin_libint_entity_h_
23 
24 #include <iomanip>
25 #include <limits>
26 #include <string>
27 #include <sstream>
28 #include <dgvertex.h>
29 #include <class_registry.h>
30 
31 namespace libint2 {
32 
36  namespace EntityTypes {
37  typedef enum {fp, integer} EntityTypeEnum;
38 
39  template <unsigned int TypeIndex>
40  struct EntityType {
41  static unsigned int type2int() {
42  return TypeIndex;
43  }
44  };
45 
46  typedef EntityType<fp> FP;
47  typedef EntityType<integer> Int;
48 
49  static const unsigned int ntypes = 2;
50  };
51 
53  template <typename T, typename U>
54  struct ProductType;
55  template <> struct ProductType<int,int> { typedef int result; };
56  template <> struct ProductType<int,double> { typedef double result; };
57  template <> struct ProductType<double,int> { typedef double result; };
58  template <> struct ProductType<double,double> { typedef double result; };
59  template <> struct ProductType<EntityTypes::Int,int> { typedef EntityTypes::Int result; };
60  template <> struct ProductType<EntityTypes::Int,double> { typedef EntityTypes::FP result; };
61  template <> struct ProductType<EntityTypes::FP,int> { typedef EntityTypes::FP result; };
62  template <> struct ProductType<EntityTypes::FP,double> { typedef EntityTypes::FP result; };
63  template <> struct ProductType<int,EntityTypes::Int> { typedef EntityTypes::Int result; };
64  template <> struct ProductType<double,EntityTypes::Int> { typedef EntityTypes::FP result; };
65  template <> struct ProductType<int,EntityTypes::FP> { typedef EntityTypes::FP result; };
66  template <> struct ProductType<double,EntityTypes::FP> { typedef EntityTypes::FP result; };
67  template <> struct ProductType<EntityTypes::Int,EntityTypes::Int> { typedef EntityTypes::Int result; };
68  template <> struct ProductType<EntityTypes::Int,EntityTypes::FP> { typedef EntityTypes::FP result; };
69  template <> struct ProductType<EntityTypes::FP,EntityTypes::Int> { typedef EntityTypes::FP result; };
70  template <> struct ProductType<EntityTypes::FP,EntityTypes::FP> { typedef EntityTypes::FP result; };
71 
73  template <typename T>
74  std::string to_string(const T& x) {
75  std::ostringstream oss; oss << std::scientific << std::setprecision(std::numeric_limits<T>::digits10 + 1) << x; return oss.str();
76  }
77 
81  class Entity
82  {
83  public:
84  virtual ~Entity() {}
86  const std::string& id() const { return id_; }
87 
88  protected:
89  Entity(const std::string& id) : id_(id) {}
90 
91  private:
93  std::string id_;
94 
95  };
96 
101  template <class T>
102  class RTimeEntity :
103  public Entity,
104  public DGVertex
105  {
106  public:
107  typedef typename DGVertex::KeyType key_type;
108 
109  RTimeEntity(const std::string& id, bool p = true) :
110  Entity(id), DGVertex(ClassInfo<RTimeEntity>::Instance().id()), precomputed_(p)
111  {
112  FNVStringHash SH;
113  key_ = KeyTypes::cast(SH.hash(id));
114 #if DEBUG
115 std::cout << "Allocated RTimeEntity id = " << this->id() << std::endl;
116 #endif
117  }
118 
119  virtual ~RTimeEntity()
120  {
121 #if DEBUG
122  std::cout << "Deallocated RTimeEntity id = " << this->id() << std::endl;
123 #endif
124  }
125 
127  unsigned int size() const { return 1; }
128 
130  bool equiv(const SafePtr<DGVertex>& a) const
131  {
132  if (a->typeid_ == typeid_) {
133 #if USE_INT_KEY_TO_COMPARE
134  return key() == a->key() && label() == a->label();
135 #else
136  SafePtr<RTimeEntity> a_cast = static_pointer_cast<RTimeEntity,DGVertex>(a);
137  return id() == a_cast->id();
138 #endif
139  }
140  else
141  return false;
142  }
143 
145  const std::string& label() const
146  {
147  return Entity::id();
148  }
150  const std::string& id() const
151  {
152  return label();
153  }
155  std::string description() const
156  {
157  ostringstream os;
158  os << "RTimeEntity: " << id();
159  const std::string descr = os.str();
160  return descr;
161  }
163  typename DGVertex::KeyReturnType key() const {
164  return key_;
165  }
166 
167  private:
169  bool this_precomputed() const
170  {
171  return precomputed_;
172  }
173 
174  key_type key_;
178  bool precomputed_;
179  };
180 
185  template <class T>
186  class CTimeEntity :
187  public Entity,
188  public DGVertex
189  {
190  public:
191  CTimeEntity(const T& val) :
192  Entity(to_string(val)), DGVertex(ClassInfo<CTimeEntity>::Instance().id()), value_(val)
193  {
194 #if DEBUG
195  std::cout << "Allocated CTimeEntity id = " << this->id() << " value = " << value() << std::endl;
196 #endif
197  }
198 
199  virtual ~CTimeEntity()
200  {
201 #if DEBUG
202  std::cout << "Deallocated CTimeEntity id = " << this->id() << " value = " << value() << std::endl;
203 #endif
204  }
205 
207  unsigned int size() const { return 1; }
208 
210  bool equiv(const SafePtr<DGVertex>& a) const
211  {
212  if (a->typeid_ == typeid_) {
213 #if USE_INT_KEY_TO_COMPARE
214  return key() == a->key();
215 #else
216  SafePtr<CTimeEntity> a_cast = static_pointer_cast<CTimeEntity,DGVertex>(a);
217  return id() == a_cast->id();
218 #endif
219  }
220  else
221  return false;
222  }
223 
225  const std::string& label() const
226  {
227  return Entity::id();
228  }
230  const std::string& id() const
231  {
232  return label();
233  }
235  std::string description() const
236  {
237  ostringstream os;
238  os << "CTimeEntity: " << id();
239  const std::string descr = os.str();
240  return descr;
241  }
242 
244  typename KeyTraits<T>::ReturnType value() const { return value_; }
245 
247  typename DGVertex::KeyReturnType key() const {
248  if (std::is_floating_point<T>::value) {
249  if (not std::is_same<T,double>::value)
250  throw std::runtime_error("CTimeEntity<Real> only supported when Real==double");
251  return static_cast<typename DGVertex::KeyReturnType>(*reinterpret_cast<const unsigned long*>(&value_));
252  }
253  else
254  return static_cast<typename DGVertex::KeyReturnType>(value());
255  }
256 
257  private:
258  T value_;
259 
261  bool this_precomputed() const
262  {
263  return true;
264  }
265 
266  };
267 
268 
272 // template <typename T>
273 // SafePtr<Entity>
274 // operator*(const SafePtr<Entity>& A, const SafePtr< CTimeEntity<T> >& B);
275 
278  template <typename T, typename U>
279  SafePtr< CTimeEntity< typename ProductType<T,U>::result > >
280  operator*(const SafePtr< CTimeEntity<T> >& A, const SafePtr< CTimeEntity<U> >& B)
281  {
283  return SafePtr<prodtype>(new prodtype(A->value()*B->value()));
284  }
285 
288  template <typename T, typename U>
289  SafePtr< RTimeEntity< typename ProductType<T,U>::result > >
290  operator*(const SafePtr< RTimeEntity<T> >& A, const SafePtr< CTimeEntity<U> >& B)
291  {
293  ostringstream oss;
294  oss << A->id() << "*" << B->id();
295  // TODO this should be false, but the logic of DirectedGraph construction depends on this being true
296  const bool not_precomputed = true;
297  return SafePtr<prodtype>(new prodtype(oss.str(), not_precomputed));
298  }
299  // TODO should be possible to enable this, but this creates RTimeEntities that should not be precomputed, see the comment above
300 #if 0
301 
303  template <typename T, typename U>
304  SafePtr< RTimeEntity< typename ProductType<T,U>::result > >
305  operator*(const SafePtr< CTimeEntity<U> >& B, const SafePtr< RTimeEntity<T> >& A)
306  {
307  return A * B;
308  }
309 #endif
310 
311 };
312 
313 #endif
314 
unsigned int size() const
Implementation of DGVertex::size()
Definition: entity.h:207
const std::string & id() const
Implementation of DGVertex::id()
Definition: entity.h:150
KeyTypes::InstanceID KeyType
DGVertex provides function key() which computes key of type KeyType and returns it using KeyReturnTyp...
Definition: dgvertex.h:61
CTimeEntity is an Entity of type T that exists at compile-time of the generated code (hence has a val...
Definition: entity.h:186
bool equiv(const SafePtr< DGVertex > &a) const
Implementation of DGVertex::equiv()
Definition: entity.h:130
Definition: entity.h:40
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
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:280
Product of 2 types.
Definition: entity.h:54
This is a vertex of a Directed Graph (DG)
Definition: dgvertex.h:43
const std::string & label() const
Implementation of DGVertex::label()
Definition: entity.h:145
unsigned int size() const
Implementation of DGVertex::size()
Definition: entity.h:127
DGVertex::KeyReturnType key() const
Implements Hashable::key()
Definition: entity.h:163
DGVertex(ClassID tid)
Sets typeid to tid.
Definition: dgvertex.cc:31
FNVStringHash uses Fowler/Noll/Vo algorithm to hash a char string to a 64-bit integer.
Definition: hashable.h:88
RTimeEntity is an Entity of type T that exists at runtime of the generated code (hence has no value k...
Definition: entity.h:102
Entity is a base class for all objects that exist at compile or runtime of the generated code.
Definition: entity.h:81
std::string to_string(const T &x)
Converts x to its string representation.
Definition: entity.h:74
DGVertex::KeyReturnType key() const
Implements Hashable::key()
Definition: entity.h:247
KeyTraits< T >::ReturnType value() const
returns the value
Definition: entity.h:244
const std::string & id() const
Implementation of DGVertex::id()
Definition: entity.h:230
const std::string & label() const
Implementation of DGVertex::label()
Definition: entity.h:225
Objects of this type provide limited information about the class at runtime.
Definition: class_registry.h:44
bool equiv(const SafePtr< DGVertex > &a) const
Implementation of DGVertex::equiv()
Definition: entity.h:210
const std::string & id() const
Return id string.
Definition: entity.h:86
std::string description() const
Implementation of DGVertex::description()
Definition: entity.h:235
LIBINT2_UINT_LEAST64 hash(const std::string &S)
Returns 64-bit integer hash of S.
Definition: hashable.h:111
ClassID typeid_
typeid stores the ClassID of the concrete type.
Definition: dgvertex.h:68
std::string description() const
Implementation of DGVertex::description()
Definition: entity.h:155