TBTK
Need a break? Support the development by playing Polarity Puzzles
Serializable.h
Go to the documentation of this file.
1 /* Copyright 2017 Kristofer Björnson
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
23 #ifndef COM_DAFER45_TBTK_SERIALIZABLE
24 #define COM_DAFER45_TBTK_SERIALIZABLE
25 
26 #include "TBTK/SpinMatrix.h"
27 #include "TBTK/Statistics.h"
28 #include "TBTK/TBTKMacros.h"
29 
30 #include <complex>
31 #include <sstream>
32 #include <type_traits>
33 #include <vector>
34 
35 namespace TBTK{
36 
37 //Forward declaration of classes that are pseudo-Serializable (that implements
38 //the Serializable interface non-virtually).
39 class Index;
40 class HoppingAmplitude;
41 template<typename DataType> class CArray;
42 
44 public:
47  enum class Mode {Debug, Binary, XML, JSON};
48 
50  virtual std::string serialize(Mode mode) const = 0;
51 
53  static bool hasID(const std::string &serialization, Mode mode);
54 
56  static std::string getID(const std::string &serialization, Mode mode);
57 
75  static std::string extractComponent(
76  const std::string &serialization,
77  const std::string &containerID,
78  const std::string &componentID,
79  const std::string &componentName,
80  Mode mode
81  );
82 protected:
84  static bool validate(
85  const std::string &serialization,
86  const std::string &id,
87  Mode mode
88  );
89 
91  static std::string getContent(
92  const std::string &serialization,
93  Mode mode
94  );
95 
97  static std::vector<std::string> split(
98  const std::string &content,
99  Mode mode
100  );
101 
108  template<typename DataType>
109  static typename std::enable_if<!std::is_pointer<DataType>::value, std::string>::type serialize(const DataType &data, Mode mode);
110  template<typename DataType>
111  static typename std::enable_if<std::is_pointer<DataType>::value, std::string>::type serialize(const DataType &data, Mode mode);
112 
121  template<typename DataType>
122  static DataType deserialize(
123  const std::string &serialization,
124  Mode mode
125  );
126 private:
128  static std::string _serialize(bool b, Mode mode);
129 
131  static void _deserialize(
132  const std::string &serialization,
133  bool *b,
134  Mode mode
135  );
136 
138  static std::string _serialize(int i, Mode mode);
139 
141  static void _deserialize(
142  const std::string &serialization,
143  int *i,
144  Mode mode
145  );
146 
148  static std::string _serialize(unsigned int u, Mode mode);
149 
151  static void _deserialize(
152  const std::string &serialization,
153  unsigned int *u,
154  Mode mode
155  );
156 
158  static std::string _serialize(double d, Mode mode);
159 
161  static void _deserialize(
162  const std::string &serialization,
163  double *d,
164  Mode mode
165  );
166 
168  static std::string _serialize(std::complex<double> c, Mode mode);
169 
171  static void _deserialize(
172  const std::string &serialization,
173  std::complex<double> *c,
174  Mode mode
175  );
176 
178  static std::string _serialize(Statistics s, Mode mode);
179 
181  static void _deserialize(
182  const std::string &serialization,
183  Statistics *s,
184  Mode mode
185  );
186 protected:
191  static std::string extract(
192  const std::string &serialization,
193  Mode mode,
194  std::string component
195  );
196 
200  friend class Index;
201  friend class HoppingAmplitude;
202  friend class SourceAmplitude;
203  friend class OverlapAmplitude;
204  template<typename DataType> friend class CArray;
205 };
206 
207 //#ifndef TBTK_DISABLE_NLOHMANN_JSON
208 template<typename DataType>
209 typename std::enable_if<!std::is_pointer<DataType>::value, std::string>::type Serializable::serialize(const DataType &data, Mode mode){
210  return data.serialize(mode);
211 }
212 
213 template<typename DataType>
214 typename std::enable_if<std::is_pointer<DataType>::value, std::string>::type Serializable::serialize(const DataType &data, Mode mode){
215  return data->serialize(mode);
216 }
217 /*template<typename DataType>
218 typename std::enable_if<true, std::string>::type Serializable::serialize(const DataType &data, Mode mode){
219  return data->serialize(mode);
220 }*/
221 //#endif
222 
223 template<>
224 inline std::string Serializable::serialize(const bool &data, Mode mode){
225  return _serialize(data, mode);
226 }
227 
228 template<>
229 inline std::string Serializable::serialize(const double &data, Mode mode){
230  return _serialize(data, mode);
231 }
232 
233 template<>
234 inline std::string Serializable::serialize(
235  const std::complex<double> &data,
236  Mode mode
237 ){
238  return _serialize(data, mode);
239 }
240 
241 template<>
242 inline std::string Serializable::serialize(const int &data, Mode mode){
243  return _serialize(data, mode);
244 }
245 
246 template<>
247 inline std::string Serializable::serialize(const unsigned int &data, Mode mode){
248  return _serialize(data, mode);
249 }
250 
251 template<>
252 inline std::string Serializable::serialize(const SpinMatrix &data, Mode mode){
253  TBTKNotYetImplemented("Serializable::serialize<SpinMatrix>()");
254 }
255 
256 template<>
257 inline std::string Serializable::serialize(const Statistics &data, Mode mode){
258  return _serialize(data, mode);
259 }
260 
261 template<>
262 inline std::string Serializable::serialize(
263  const std::vector<std::complex<double>> &data,
264  Mode mode
265 ){
266  TBTKNotYetImplemented(
267  "Serializable::serialize<std::vector<std::complex<double>>>()"
268  );
269 }
270 
271 template<typename DataType>
272 DataType Serializable::deserialize(const std::string &serialization, Mode mode){
273  return DataType(serialization, mode);
274 }
275 
276 template<>
277 inline int Serializable::deserialize(const std::string &serialization, Mode mode){
278  int i;
279  _deserialize(serialization, &i, mode);
280  return i;
281 }
282 
283 template<>
284 inline unsigned int Serializable::deserialize(const std::string &serialization, Mode mode){
285  unsigned int i;
286  _deserialize(serialization, &i, mode);
287  return i;
288 }
289 
290 template<>
291 inline double Serializable::deserialize(const std::string &serialization, Mode mode){
292  double d;
293  _deserialize(serialization, &d, mode);
294  return d;
295 }
296 
297 template<>
298 inline std::complex<double> Serializable::deserialize(
299  const std::string &serialization,
300  Mode mode
301 ){
302  std::complex<double> c;
303  _deserialize(serialization, &c, mode);
304  return c;
305 }
306 
307 template<>
308 inline SpinMatrix Serializable::deserialize(
309  const std::string &serialization,
310  Mode mode
311 ){
312  TBTKNotYetImplemented("Serializable::deserialize<SpinMatrix>()");
313 }
314 
315 template<>
317  const std::string &serialization,
318  Mode mode
319 ){
320  Statistics s;
321  _deserialize(serialization, &s, mode);
322  return s;
323 }
324 
325 template<>
326 inline std::vector<std::complex<double>> Serializable::deserialize(
327  const std::string &serialization,
328  Mode mode
329 ){
330  TBTKNotYetImplemented(
331  "Serializable::deserialize<std::vector<std::complex<double>>>()"
332  );
333 }
334 
335 inline std::string Serializable::_serialize(bool b, Mode mode){
336  switch(mode){
337  case Mode::Debug:
338  case Mode::JSON:
339  {
340  std::stringstream ss;
341  ss << b;
342 
343  return ss.str();
344  }
345  default:
346  TBTKExit(
347  "Serializable::serialize()",
348  "Only Mode::Debug is supported yet.",
349  ""
350  );
351  }
352 }
353 
354 inline void Serializable::_deserialize(
355  const std::string &serialization,
356  bool *b,
357  Mode mode
358 ){
359  switch(mode){
360  case Mode::Debug:
361  case Mode::JSON:
362  {
363  std::stringstream ss;
364  ss.str(serialization);
365  ss >> *b;
366 
367  break;
368  }
369  default:
370  TBTKExit(
371  "Serializable::deserialize()",
372  "Only Mode::Debug is supported yet.",
373  ""
374  );
375  }
376 }
377 
378 inline std::string Serializable::_serialize(int i, Mode mode){
379  switch(mode){
380  case Mode::Debug:
381  case Mode::JSON:
382  {
383  std::stringstream ss;
384  ss << i;
385 
386  return ss.str();
387  }
388  default:
389  TBTKExit(
390  "Serializable::serialize()",
391  "Only Mode::Debug is supported yet.",
392  ""
393  );
394  }
395 }
396 
397 inline void Serializable::_deserialize(
398  const std::string &serialization,
399  int *i,
400  Mode mode
401 ){
402  switch(mode){
403  case Mode::Debug:
404  case Mode::JSON:
405  {
406  std::stringstream ss;
407  ss.str(serialization);
408  ss >> *i;
409 
410  break;
411  }
412  default:
413  TBTKExit(
414  "Serializable::deserialize()",
415  "Only Mode::Debug is supported yet.",
416  ""
417  );
418  }
419 }
420 
421 inline std::string Serializable::_serialize(unsigned int u, Mode mode){
422  switch(mode){
423  case Mode::Debug:
424  case Mode::JSON:
425  {
426  std::stringstream ss;
427  ss << u;
428 
429  return ss.str();
430  }
431  default:
432  TBTKExit(
433  "Serializable::serialize()",
434  "Only Mode::Debug is supported yet.",
435  ""
436  );
437  }
438 }
439 
440 inline void Serializable::_deserialize(
441  const std::string &serialization,
442  unsigned int *u,
443  Mode mode
444 ){
445  switch(mode){
446  case Mode::Debug:
447  case Mode::JSON:
448  {
449  std::stringstream ss;
450  ss.str(serialization);
451  ss >> *u;
452 
453  break;
454  }
455  default:
456  TBTKExit(
457  "Serializable::deserialize()",
458  "Only Mode::Debug is supported yet.",
459  ""
460  );
461  }
462 }
463 
464 inline std::string Serializable::_serialize(double d, Mode mode){
465  switch(mode){
466  case Mode::Debug:
467  case Mode::JSON:
468  {
469  std::stringstream ss;
470  ss << d;
471 
472  return ss.str();
473  }
474  default:
475  TBTKExit(
476  "Serializable::serialize()",
477  "Only Mode::Debug is supported yet.",
478  ""
479  );
480  }
481 }
482 
483 inline void Serializable::_deserialize(
484  const std::string &serialization,
485  double *d,
486  Mode mode
487 ){
488  switch(mode){
489  case Mode::Debug:
490  case Mode::JSON:
491  {
492  std::stringstream ss;
493  ss.str(serialization);
494  ss >> *d;
495 
496  break;
497  }
498  default:
499  TBTKExit(
500  "Serializable::deserialize()",
501  "Only Mode::Debug is supported yet.",
502  ""
503  );
504  }
505 }
506 
507 inline std::string Serializable::_serialize(std::complex<double> c, Mode mode){
508  switch(mode){
509  case Mode::Debug:
510  case Mode::JSON:
511  {
512  std::stringstream ss;
513  ss << c;
514 
515  return ss.str();
516  }
517  default:
518  TBTKExit(
519  "Serializable::serialize()",
520  "Only Mode::Debug is supported yet.",
521  ""
522  );
523  }
524 }
525 
526 inline void Serializable::_deserialize(
527  const std::string &serialization,
528  std::complex<double> *c,
529  Mode mode
530 ){
531  switch(mode){
532  case Mode::Debug:
533  case Mode::JSON:
534  {
535  std::stringstream ss;
536  ss.str(serialization);
537  ss >> *c;
538 
539  break;
540  }
541  default:
542  TBTKExit(
543  "Serializable::deserialize()",
544  "Only Mode::Debug is supported yet.",
545  ""
546  );
547  }
548 }
549 
550 inline std::string Serializable::_serialize(Statistics statistics, Mode mode){
551  switch(mode){
552  case Mode::Debug:
553  {
554  std::stringstream ss;
555  switch(statistics){
556  case Statistics::FermiDirac:
557  case Statistics::BoseEinstein:
558  ss << static_cast<int>(statistics);
559  break;
560  default:
561  TBTKExit(
562  "Serializable::serialize()",
563  "Unknown Statistics type '" << static_cast<int>(statistics) << "'",
564  "This should never happen, contact the developer."
565  );
566  }
567 
568  return ss.str();
569  }
570  case Mode::JSON:
571  {
572  std::stringstream ss;
573  switch(statistics){
574  case Statistics::FermiDirac:
575  ss << "FermiDirac";
576  break;
577  case Statistics::BoseEinstein:
578  ss << "BoseEinstein";
579  break;
580  default:
581  TBTKExit(
582  "Serializable::serialize()",
583  "Unknown Statistics type '" << static_cast<int>(statistics) << "'",
584  "This should never happen, contact the developer."
585  );
586  }
587 
588  return ss.str();
589  }
590  default:
591  TBTKExit(
592  "Serializable::serialize()",
593  "Only Mode::Debug is supported yet.",
594  ""
595  );
596  }
597 }
598 
599 inline void Serializable::_deserialize(
600  const std::string &serialization,
601  Statistics *statistics,
602  Mode mode
603 ){
604  switch(mode){
605  case Mode::Debug:
606  {
607  std::stringstream ss;
608  ss.str(serialization);
609  int i;
610  ss >> i;
611  switch(i){
612  case static_cast<int>(Statistics::FermiDirac):
613  *statistics = Statistics::FermiDirac;
614  break;
615  case static_cast<int>(Statistics::BoseEinstein):
616  *statistics = Statistics::BoseEinstein;
617  break;
618  default:
619  TBTKExit(
620  "Serializable::serialize()",
621  "Unknown Statistics type '" << i << "'",
622  "The serialization string is either corrupted"
623  << " or the the serialization was created with"
624  << " a newer version of TBTK that supports"
625  << " more types of Statistics."
626  );
627  }
628 
629  break;
630  }
631  case Mode::JSON:
632  {
633  if(serialization.compare("FermiDirac") == 0){
634  *statistics = Statistics::FermiDirac;
635  }
636  else if(serialization.compare("BoseEinstein") == 0){
637  *statistics = Statistics::BoseEinstein;
638  }
639  else{
640  TBTKExit(
641  "Serializable::serialize()",
642  "Unknown Statistics type '" << serialization
643  << "'",
644  "The serialization string is either corrupted"
645  << " or the the serialization was created with"
646  << " a newer version of TBTK that supports"
647  << " more types of Statistics."
648  );
649  }
650 
651  break;
652  }
653  default:
654  TBTKExit(
655  "Serializable::deserialize()",
656  "Only Mode::Debug is supported yet.",
657  ""
658  );
659  }
660 }
661 
662 }; //End namespace TBTK
663 
664 #endif
TBTK::OverlapAmplitude
Overlap amplitude between state 'bra' and 'ket'.
Definition: OverlapAmplitude.h:37
TBTK::Statistics
Statistics
Definition: Statistics.h:29
TBTK::Serializable::getContent
static std::string getContent(const std::string &serialization, Mode mode)
TBTK::Serializable::validate
static bool validate(const std::string &serialization, const std::string &id, Mode mode)
TBTK::CArray
Container for a C style array.
Definition: CArray.h:44
TBTK::Serializable::extractComponent
static std::string extractComponent(const std::string &serialization, const std::string &containerID, const std::string &componentID, const std::string &componentName, Mode mode)
TBTK::Serializable::serialize
virtual std::string serialize(Mode mode) const =0
TBTK::Serializable
Definition: Serializable.h:43
TBTK::SourceAmplitude
Source amplitude for equations with a source term.
Definition: SourceAmplitude.h:40
TBTK::Serializable::hasID
static bool hasID(const std::string &serialization, Mode mode)
TBTK::Serializable::split
static std::vector< std::string > split(const std::string &content, Mode mode)
TBTK::HoppingAmplitude
Hopping amplitude from state 'from' to state 'to'.
Definition: HoppingAmplitude.h:53
Statistics.h
Enum class for Fermi-Dirac and Bose-Einstein statistics.
TBTK::Serializable::getID
static std::string getID(const std::string &serialization, Mode mode)
TBTKMacros.h
Precompiler macros.
TBTK::Serializable::Mode
Mode
Definition: Serializable.h:47
TBTK::Serializable::deserialize
static DataType deserialize(const std::string &serialization, Mode mode)
Definition: Serializable.h:272
TBTK::Index
Physical index.
Definition: Index.h:44
TBTK::Serializable::extract
static std::string extract(const std::string &serialization, Mode mode, std::string component)