TBTK
AbstractProperty.h
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_ABSTRACT_PROPERTY
24 #define COM_DAFER45_TBTK_ABSTRACT_PROPERTY
25 
27 #include "TBTK/SpinMatrix.h"
28 #include "TBTK/TBTKMacros.h"
29 
30 #include "TBTK/json.hpp"
31 
32 namespace TBTK{
33 namespace Property{
34 
90 template<
91  typename DataType,
92  bool isFundamental = std::is_fundamental<DataType>::value,
93  bool isSerializable = std::is_base_of<Serializable, DataType>::value
94 >
96 public:
100  unsigned int getBlockSize() const;
101 
106  unsigned int getSize() const;
107 
112  const std::vector<DataType>& getData() const;
113 
119  std::vector<DataType>& getDataRW();
120 
125  unsigned int getDimensions() const;
126 
132  std::vector<int> getRanges() const;
133 
140  int getOffset(const Index &index) const;
141 
146  const IndexDescriptor& getIndexDescriptor() const;
147 
154  bool contains(const Index &index) const;
155 
172  virtual const DataType& operator()(
173  const Index &index,
174  unsigned int offset = 0
175  ) const;
176 
194  virtual DataType& operator()(
195  const Index &index,
196  unsigned int offset = 0
197  );
198 
208  DataType& operator()(const std::initializer_list<int> &index);
209 
219  const DataType& operator()(
220  const std::initializer_list<int> &index
221  ) const;
222 
232  DataType& operator()(const std::initializer_list<unsigned int> &index);
233 
243  const DataType& operator()(
244  const std::initializer_list<unsigned int> &index
245  ) const;
246 
254  virtual const DataType& operator()(unsigned int offset) const;
255 
263  virtual DataType& operator()(unsigned int offset);
264 
274  void setAllowIndexOutOfBoundsAccess(bool allowIndexOutOfBoundsAccess);
275 
284  void setDefaultValue(const DataType &defaultValue);
285 
287  virtual std::string serialize(Mode mode) const;
288 protected:
291 
296  AbstractProperty(unsigned int blockSize);
297 
306  unsigned int blockSize,
307  const DataType *data
308  );
309 
319  unsigned int dimensions,
320  const int *ranges,
321  unsigned int blockSize
322  );
323 
336  unsigned int dimensions,
337  const int *ranges,
338  unsigned int blockSize,
339  const DataType *data
340  );
341 
349  const IndexTree &indexTree,
350  unsigned int blockSize
351  );
352 
362  const IndexTree &indexTree,
363  unsigned int blockSize,
364  const DataType *data
365  );
366 
370  AbstractProperty(const AbstractProperty &abstractProperty);
371 
375  AbstractProperty(AbstractProperty &&abstractProperty);
376 
385  const std::string &serialization,
386  Mode mode
387  );
388 
390  virtual ~AbstractProperty();
391 
397  AbstractProperty& operator=(const AbstractProperty &abstractProperty);
398 
404  AbstractProperty& operator=(AbstractProperty &&abstractProperty);
405 private:
407  IndexDescriptor indexDescriptor;
408 
412  unsigned int blockSize;
413 
415  std::vector<DataType> data;
416 
418  bool allowIndexOutOfBoundsAccess;
419 
421  DataType defaultValue;
422 
433  virtual void calculateDynamically(const Index &index, DataType *block);
434 };
435 
436 template<typename DataType, bool isFundamental, bool isSerializable>
437 inline unsigned int AbstractProperty<
438  DataType,
439  isFundamental,
440  isSerializable
441 >::getBlockSize() const{
442  return blockSize;
443 }
444 
445 template<typename DataType, bool isFundamental, bool isSerializable>
446 inline unsigned int AbstractProperty<
447  DataType,
448  isFundamental,
449  isSerializable
450 >::getSize() const{
451  return data.size();
452 }
453 
454 template<typename DataType, bool isFundamental, bool isSerializable>
455 inline const std::vector<DataType>& AbstractProperty<
456  DataType,
457  isFundamental,
458  isSerializable
459 >::getData() const{
460  return data;
461 }
462 
463 template<typename DataType, bool isFundamental, bool isSerializable>
464 inline std::vector<DataType>& AbstractProperty<
465  DataType,
466  isFundamental,
467  isSerializable
469  return data;
470 }
471 
472 template<typename DataType, bool isFundamental, bool isSerializable>
473 inline unsigned int AbstractProperty<
474  DataType,
475  isFundamental,
476  isSerializable
478  return indexDescriptor.getDimensions();
479 }
480 
481 template<typename DataType, bool isFundamental, bool isSerializable>
482 inline std::vector<int> AbstractProperty<
483  DataType,
484  isFundamental,
485  isSerializable
486 >::getRanges() const{
487  return indexDescriptor.getRanges();
488 }
489 
490 template<typename DataType, bool isFundamental, bool isSerializable>
491 inline int AbstractProperty<
492  DataType,
493  isFundamental,
494  isSerializable
496  const Index &index
497 ) const{
498  return blockSize*indexDescriptor.getLinearIndex(
499  index,
500  allowIndexOutOfBoundsAccess
501  );
502 }
503 
504 template<typename DataType, bool isFundamental, bool isSerializable>
505 inline const IndexDescriptor& AbstractProperty<
506  DataType,
507  isFundamental,
508  isSerializable
510 ) const{
511  return indexDescriptor;
512 }
513 
514 template<typename DataType, bool isFundamental, bool isSerializable>
515 inline bool AbstractProperty<
516  DataType,
517  isFundamental,
518  isSerializable
520  const Index &index
521 ) const{
522  return indexDescriptor.contains(index);
523 }
524 
525 template<typename DataType, bool isFundamental, bool isSerializable>
526 inline const DataType& AbstractProperty<
527  DataType,
528  isFundamental,
529  isSerializable
530 >::operator()(
531  const Index &index,
532  unsigned int offset
533 ) const{
534  int indexOffset = getOffset(index);
535  if(indexOffset < 0)
536  return defaultValue;
537  else
538  return data[indexOffset + offset];
539 }
540 
541 template<typename DataType, bool isFundamental, bool isSerializable>
542 inline DataType& AbstractProperty<
543  DataType,
544  isFundamental,
545  isSerializable
546 >::operator()(
547  const Index &index,
548  unsigned int offset
549 ){
550  int indexOffset = getOffset(index);
551  if(indexOffset < 0){
552  static DataType defaultValueNonConst;
553  defaultValueNonConst = defaultValue;
554  return defaultValueNonConst;
555  }
556  else{
557  return data[indexOffset + offset];
558  }
559 }
560 
561 template<typename DataType, bool isFundamental, bool isSerializeable>
562 inline DataType& AbstractProperty<
563  DataType,
564  isFundamental,
565  isSerializeable
566 >::operator()(const std::initializer_list<int> &index){
567  return operator()(index, 0);
568 }
569 
570 template<typename DataType, bool isFundamental, bool isSerializeable>
571 inline const DataType& AbstractProperty<
572  DataType,
573  isFundamental,
574  isSerializeable
575 >::operator()(const std::initializer_list<int> &index) const{
576  return operator()(index, 0);
577 }
578 
579 template<typename DataType, bool isFundamental, bool isSerializeable>
580 inline DataType& AbstractProperty<
581  DataType,
582  isFundamental,
583  isSerializeable
584 >::operator()(const std::initializer_list<unsigned int> &index){
585  return operator()(index, 0);
586 }
587 
588 template<typename DataType, bool isFundamental, bool isSerializeable>
589 inline const DataType& AbstractProperty<
590  DataType,
591  isFundamental,
592  isSerializeable
593 >::operator()(const std::initializer_list<unsigned int> &index) const{
594  return operator()(index, 0);
595 }
596 
597 template<typename DataType, bool isFundamental, bool isSerializable>
598 inline const DataType& AbstractProperty<
599  DataType,
600  isFundamental,
601  isSerializable
602 >::operator()(unsigned int offset) const{
603  return data[offset];
604 }
605 
606 template<typename DataType, bool isFundamental, bool isSerializable>
607 inline DataType& AbstractProperty<
608  DataType,
609  isFundamental,
610  isSerializable
611 >::operator()(unsigned int offset){
612  return data[offset];
613 }
614 
615 template<typename DataType, bool isFundamental, bool isSerializable>
616 inline void AbstractProperty<
617  DataType,
618  isFundamental,
619  isSerializable
620 >::setAllowIndexOutOfBoundsAccess(bool allowIndexOutOfBoundsAccess){
621  this->allowIndexOutOfBoundsAccess = allowIndexOutOfBoundsAccess;
622 }
623 
624 template<typename DataType, bool isFundamental, bool isSerializable>
625 inline void AbstractProperty<
626  DataType,
627  isFundamental,
628  isSerializable
629 >::setDefaultValue(const DataType &defaultValue){
630  this->defaultValue = defaultValue;
631 }
632 
633 template<>
634 inline std::string AbstractProperty<
635  bool,
636  true,
637  false
638 >::serialize(Mode mode) const{
639  switch(mode){
640  case Mode::JSON:
641  {
642  nlohmann::json j;
643  j["id"] = "AbstractProperty";
644  j["indexDescriptor"] = nlohmann::json::parse(
645  indexDescriptor.serialize(mode)
646  );
647  j["blockSize"] = blockSize;
648  for(unsigned int n = 0; n < data.size(); n++){
649  //Convert the reference data[n] to an actual bool to
650  //get the code to compile on Mac. Some issue with the
651  //nlohmann library on Mac. Replace by the single
652  //commented out line when it is working again.
653  bool d = data[n];
654  j["data"].push_back(d);
655 // j["data"].push_back(data[n]);
656  }
657 
658  j["allowIndexOutOfBoundsAccess"] = allowIndexOutOfBoundsAccess;
659  j["defaultValue"] = defaultValue;
660 
661  return j.dump();
662  }
663  default:
664  TBTKExit(
665  "AbstractProperty<DataType>::serialize()",
666  "Only Serializable::Mode::JSON is supported yet.",
667  ""
668  );
669  }
670 }
671 
672 template<>
673 inline std::string AbstractProperty<
674  char,
675  true,
676  false
677 >::serialize(Mode mode) const{
678  switch(mode){
679  case Mode::JSON:
680  {
681  nlohmann::json j;
682  j["id"] = "AbstractProperty";
683  j["indexDescriptor"] = nlohmann::json::parse(
684  indexDescriptor.serialize(mode)
685  );
686  j["blockSize"] = blockSize;
687  for(unsigned int n = 0; n < data.size(); n++)
688  j["data"].push_back(data[n]);
689 
690  j["allowIndexOutOfBoundsAccess"] = allowIndexOutOfBoundsAccess;
691  j["defaultValue"] = defaultValue;
692 
693  return j.dump();
694  }
695  default:
696  TBTKExit(
697  "AbstractProperty<DataType>::serialize()",
698  "Only Serializable::Mode::JSON is supported yet.",
699  ""
700  );
701  }
702 }
703 
704 template<>
705 inline std::string AbstractProperty<
706  int,
707  true,
708  false
709 >::serialize(Mode mode) const{
710  switch(mode){
711  case Mode::JSON:
712  {
713  nlohmann::json j;
714  j["id"] = "AbstractProperty";
715  j["indexDescriptor"] = nlohmann::json::parse(
716  indexDescriptor.serialize(mode)
717  );
718  j["blockSize"] = blockSize;
719  for(unsigned int n = 0; n < data.size(); n++)
720  j["data"].push_back(data[n]);
721 
722  j["allowIndexOutOfBoundsAccess"] = allowIndexOutOfBoundsAccess;
723  j["defaultValue"] = defaultValue;
724 
725  return j.dump();
726  }
727  default:
728  TBTKExit(
729  "AbstractProperty<DataType>::serialize()",
730  "Only Serializable::Mode::JSON is supported yet.",
731  ""
732  );
733  }
734 }
735 
736 template<>
737 inline std::string AbstractProperty<
738  float,
739  true,
740  false
741 >::serialize(Mode mode) const{
742  switch(mode){
743  case Mode::JSON:
744  {
745  nlohmann::json j;
746  j["id"] = "AbstractProperty";
747  j["indexDescriptor"] = nlohmann::json::parse(
748  indexDescriptor.serialize(mode)
749  );
750  j["blockSize"] = blockSize;
751  for(unsigned int n = 0; n < data.size(); n++)
752  j["data"].push_back(data[n]);
753 
754  j["allowIndexOutOfBoundsAccess"] = allowIndexOutOfBoundsAccess;
755  j["defaultValue"] = defaultValue;
756 
757  return j.dump();
758  }
759  default:
760  TBTKExit(
761  "AbstractProperty<DataType>::serialize()",
762  "Only Serializable::Mode::JSON is supported yet.",
763  ""
764  );
765  }
766 }
767 
768 template<>
769 inline std::string AbstractProperty<
770  double,
771  true,
772  false
773 >::serialize(Mode mode) const{
774  switch(mode){
775  case Mode::JSON:
776  {
777  nlohmann::json j;
778  j["id"] = "AbstractProperty";
779  j["indexDescriptor"] = nlohmann::json::parse(
780  indexDescriptor.serialize(mode)
781  );
782  j["blockSize"] = blockSize;
783  for(unsigned int n = 0; n < data.size(); n++)
784  j["data"].push_back(data[n]);
785 
786  j["allowIndexOutOfBoundsAccess"] = allowIndexOutOfBoundsAccess;
787  j["defaultValue"] = defaultValue;
788 
789  return j.dump();
790  }
791  default:
792  TBTKExit(
793  "AbstractProperty<DataType>::serialize()",
794  "Only Serializable::Mode::JSON is supported yet.",
795  ""
796  );
797  }
798 }
799 
800 template<>
801 inline std::string AbstractProperty<std::complex<double>, false, false>::serialize(Mode mode) const{
802  switch(mode){
803  case Mode::JSON:
804  {
805  nlohmann::json j;
806  j["id"] = "AbstractProperty";
807  j["indexDescriptor"] = nlohmann::json::parse(
808  indexDescriptor.serialize(mode)
809  );
810  j["blockSize"] = blockSize;
811  for(unsigned int n = 0; n < data.size(); n++){
812  std::string s = Serializable::serialize(data[n], mode);
813  j["data"].push_back(s);
814  }
815 
816  j["allowIndexOutOfBoundsAccess"] = allowIndexOutOfBoundsAccess;
817  j["defaultValue"] = Serializable::serialize(defaultValue, mode);
818 
819  return j.dump();
820  }
821  default:
822  TBTKExit(
823  "AbstractProperty<DataType>::serialize()",
824  "Only Serializable::Mode::JSON is supported yet.",
825  ""
826  );
827  }
828 }
829 
830 template<>
832  TBTKNotYetImplemented("AbstractProperty<SpinMatrix, false, false>::serialize()");
833 }
834 
835 template<typename DataType, bool isFundamental, bool isSerializable>
837  DataType,
838  isFundamental,
839  isSerializable
841  indexDescriptor(IndexDescriptor::Format::None)
842 {
843  this->blockSize = 0;
844 
845  allowIndexOutOfBoundsAccess = false;
846 }
847 
848 template<typename DataType, bool isFundamental, bool isSerializable>
850  DataType,
851  isFundamental,
852  isSerializable
854  unsigned int blockSize
855 ) :
856  indexDescriptor(IndexDescriptor::Format::None)
857 {
858  this->blockSize = blockSize;
859 
860  unsigned int size = blockSize;
861  data.reserve(size);
862  for(unsigned int n = 0; n < size; n++)
863  data.push_back(0.);
864 
865  allowIndexOutOfBoundsAccess = false;
866 }
867 
868 template<typename DataType, bool isFundamental, bool isSerializable>
870  DataType,
871  isFundamental,
872  isSerializable
874  unsigned int blockSize,
875  const DataType *data
876 ) :
877  indexDescriptor(IndexDescriptor::Format::None)
878 {
879  this->blockSize = blockSize;
880 
881  unsigned int size = blockSize;
882  this->data.reserve(size);
883  for(unsigned int n = 0; n < size; n++)
884  this->data.push_back(data[n]);
885 
886  allowIndexOutOfBoundsAccess = false;
887 }
888 
889 template<typename DataType, bool isFundamental, bool isSerializable>
891  DataType,
892  isFundamental,
893  isSerializable
895  unsigned int dimensions,
896  const int *ranges,
897  unsigned int blockSize
898 ) :
899  indexDescriptor(IndexDescriptor::Format::Ranges)
900 {
901  this->blockSize = blockSize;
902 
903  indexDescriptor.setRanges(ranges, dimensions);
904 
905  unsigned int size = blockSize*indexDescriptor.getSize();
906  data.reserve(size);
907  for(unsigned int n = 0; n < size; n++)
908  data.push_back(DataType(0.));
909 
910  allowIndexOutOfBoundsAccess = false;
911 }
912 
913 template<typename DataType, bool isFundamental, bool isSerializable>
915  DataType,
916  isFundamental,
917  isSerializable
919  unsigned int dimensions,
920  const int *ranges,
921  unsigned int blockSize,
922  const DataType *data
923 ) :
924  indexDescriptor(IndexDescriptor::Format::Ranges)
925 {
926  this->blockSize = blockSize;
927 
928  indexDescriptor.setRanges(ranges, dimensions);
929 
930  unsigned int size = blockSize*indexDescriptor.getSize();
931  this->data.reserve(size);
932  for(unsigned int n = 0; n < size; n++)
933  this->data.push_back(data[n]);
934 
935  allowIndexOutOfBoundsAccess = false;
936 }
937 
938 template<typename DataType, bool isFundamental, bool isSerializable>
940  DataType,
941  isFundamental,
942  isSerializable
944  const IndexTree &indexTree,
945  unsigned int blockSize
946 ) :
947  indexDescriptor(IndexDescriptor::Format::Custom)
948 {
949  TBTKAssert(
950  indexTree.getLinearMapIsGenerated(),
951  "AbstractProperty::AbstractProperty()",
952  "Linear map not constructed for the IndexTree.",
953  "Call IndexTree::generateLinearIndex() before passing the"
954  " IndexTree to the AbstractProperty constructor."
955  );
956 
957  this->blockSize = blockSize;
958 
959  indexDescriptor.setIndexTree(indexTree);
960 
961  unsigned int size = blockSize*indexDescriptor.getSize();
962  data.reserve(size);
963  for(unsigned int n = 0; n < size; n++)
964  data.push_back(DataType(0.));
965 
966  allowIndexOutOfBoundsAccess = false;
967 }
968 
969 template<typename DataType, bool isFundamental, bool isSerializable>
971  DataType,
972  isFundamental,
973  isSerializable
975  const IndexTree &indexTree,
976  unsigned int blockSize,
977  const DataType *data
978 ) :
979  indexDescriptor(IndexDescriptor::Format::Custom)
980 {
981  TBTKAssert(
982  indexTree.getLinearMapIsGenerated(),
983  "AbstractProperty::AbstractProperty()",
984  "Linear map not constructed for the IndexTree.",
985  "Call IndexTree::generateLinearIndex() before passing the"
986  " IndexTree to the AbstractProperty constructor."
987  );
988 
989  this->blockSize = blockSize;
990 
991  indexDescriptor.setIndexTree(indexTree);
992 
993  unsigned int size = blockSize*indexDescriptor.getSize();
994  this->data.reserve(size);
995  for(unsigned int n = 0; n < size; n++)
996  this->data.push_back(data[n]);
997 
998  allowIndexOutOfBoundsAccess = false;
999 }
1000 
1001 template<typename DataType, bool isFundamental, bool isSerializable>
1003  DataType,
1004  isFundamental,
1005  isSerializable
1007  const AbstractProperty &abstractProperty
1008 ) :
1009  indexDescriptor(abstractProperty.indexDescriptor)
1010 {
1011  blockSize = abstractProperty.blockSize;
1012 
1013  data = abstractProperty.data;
1014 
1015  allowIndexOutOfBoundsAccess
1016  = abstractProperty.allowIndexOutOfBoundsAccess;
1017 }
1018 
1019 template<typename DataType, bool isFundamental, bool isSerializable>
1021  DataType,
1022  isFundamental,
1023  isSerializable
1025  AbstractProperty &&abstractProperty
1026 ) :
1027  indexDescriptor(std::move(abstractProperty.indexDescriptor))
1028 {
1029  blockSize = abstractProperty.blockSize;
1030 
1031  data = abstractProperty.data;
1032 
1033  allowIndexOutOfBoundsAccess
1034  = abstractProperty.allowIndexOutOfBoundsAccess;
1035 }
1036 
1037 template<>
1039  const std::string &serialization,
1040  Mode mode
1041 ) :
1042  indexDescriptor(
1043  Serializable::extract(serialization, mode, "indexDescriptor"),
1044  mode
1045  )
1046 {
1047  TBTKAssert(
1048  validate(serialization, "AbstractProperty", mode),
1049  "AbstractProperty::AbstractProperty()",
1050  "Unable to parse string as AbstractProperty '" << serialization
1051  << "'.",
1052  ""
1053  );
1054 
1055  switch(mode){
1056  case Mode::JSON:
1057  try{
1058  nlohmann::json j = nlohmann::json::parse(serialization);
1059  blockSize = j.at("blockSize").get<unsigned int>();
1060  nlohmann::json d = j.at("data");
1061  for(
1062  nlohmann::json::iterator it = d.begin();
1063  it < d.end();
1064  ++it
1065  ){
1066  data.push_back(*it);
1067  }
1068 
1069  allowIndexOutOfBoundsAccess = j.at(
1070  "allowIndexOutOfBoundsAccess"
1071  ).get<bool>();
1072  defaultValue = j.at("defaultValue").get<double>();
1073  }
1074  catch(nlohmann::json::exception e){
1075  TBTKExit(
1076  "AbstractProperty::AbstractProperty()",
1077  "Unable to parse string as AbstractProperty '"
1078  << serialization << "'.",
1079  ""
1080  );
1081  }
1082 
1083  break;
1084  default:
1085  TBTKExit(
1086  "AbstractProperty::AbstractProperty()",
1087  "Only Serializable::Mode::JSON is supported yet.",
1088  ""
1089  );
1090  }
1091 }
1092 
1093 template<>
1095  const std::string &serialization,
1096  Mode mode
1097 ) :
1098  indexDescriptor(
1099  Serializable::extract(serialization, mode, "indexDescriptor"),
1100  mode
1101  )
1102 {
1103  TBTKAssert(
1104  validate(serialization, "AbstractProperty", mode),
1105  "AbstractProperty::AbstractProperty()",
1106  "Unable to parse string as AbstractProperty '" << serialization
1107  << "'.",
1108  ""
1109  );
1110 
1111  switch(mode){
1112  case Mode::JSON:
1113  try{
1114  nlohmann::json j = nlohmann::json::parse(serialization);
1115  blockSize = j.at("blockSize").get<unsigned int>();
1116  nlohmann::json d = j.at("data");
1117  for(
1118  nlohmann::json::iterator it = d.begin();
1119  it < d.end();
1120  ++it
1121  ){
1122  data.push_back(*it);
1123  }
1124 
1125  allowIndexOutOfBoundsAccess = j.at(
1126  "allowIndexOutOfBoundsAccess"
1127  ).get<bool>();
1128  defaultValue = j.at("defaultValue").get<double>();
1129  }
1130  catch(nlohmann::json::exception e){
1131  TBTKExit(
1132  "AbstractProperty::AbstractProperty()",
1133  "Unable to parse string as AbstractProperty '"
1134  << serialization << "'.",
1135  ""
1136  );
1137  }
1138 
1139  break;
1140  default:
1141  TBTKExit(
1142  "AbstractProperty::AbstractProperty()",
1143  "Only Serializable::Mode::JSON is supported yet.",
1144  ""
1145  );
1146  }
1147 }
1148 
1149 template<>
1150 inline AbstractProperty<std::complex<double>, false, false>::AbstractProperty(
1151  const std::string &serialization,
1152  Mode mode
1153 ) :
1154  indexDescriptor(
1155  Serializable::extract(serialization, mode, "indexDescriptor"),
1156  mode
1157  )
1158 {
1159  TBTKAssert(
1160  validate(serialization, "AbstractProperty", mode),
1161  "AbstractProperty::AbstractProperty()",
1162  "Unable to parse string as AbstractProperty '" << serialization
1163  << "'.",
1164  ""
1165  );
1166 
1167  switch(mode){
1168  case Mode::JSON:
1169  try{
1170  nlohmann::json j = nlohmann::json::parse(serialization);
1171  blockSize = j.at("blockSize").get<unsigned int>();
1172  nlohmann::json d = j.at("data");
1173  for(
1174  nlohmann::json::iterator it = d.begin();
1175  it < d.end();
1176  ++it
1177  ){
1178  std::complex<double> c;
1179  Serializable::deserialize(it->get<std::string>(), &c, mode);
1180  data.push_back(c);
1181  }
1182 
1183  allowIndexOutOfBoundsAccess = j.at(
1184  "allowIndexOutOfBoundsAccess"
1185  ).get<bool>();
1187  j.at("defaultValue").get<std::string>(),
1188  &defaultValue,
1189  mode
1190  );
1191  }
1192  catch(nlohmann::json::exception e){
1193  TBTKExit(
1194  "AbstractProperty::AbstractProperty()",
1195  "Unable to parse string as AbstractProperty '"
1196  << serialization << "'.",
1197  ""
1198  );
1199  }
1200 
1201  break;
1202  default:
1203  TBTKExit(
1204  "AbstractProperty::AbstractProperty()",
1205  "Only Serializable::Mode::JSON is supported yet.",
1206  ""
1207  );
1208  }
1209 }
1210 
1211 template<>
1213  const std::string &serialization,
1214  Mode mode
1215 ) :
1216  indexDescriptor(
1217  Serializable::extract(serialization, mode, "indexDescriptor"),
1218  mode
1219  )
1220 {
1221  TBTKNotYetImplemented("AbstractProperty<SpinMatrix, false, false>::AbstractProperty()");
1222 }
1223 
1224 template<typename DataType, bool isFundamental, bool isSerializable>
1225 inline AbstractProperty<
1226  DataType,
1227  isFundamental,
1228  isSerializable
1230 }
1231 
1232 template<typename DataType, bool isFundamental, bool isSerializable>
1234  DataType,
1235  isFundamental,
1236  isSerializable
1237 >& AbstractProperty<
1238  DataType,
1239  isFundamental,
1240  isSerializable
1241 >::operator=(
1242  const AbstractProperty &rhs
1243 ){
1244  if(this != &rhs){
1245  indexDescriptor = rhs.indexDescriptor;
1246 
1247  blockSize = rhs.blockSize;
1248 
1249  data = rhs.data;
1250 
1251  allowIndexOutOfBoundsAccess = rhs.allowIndexOutOfBoundsAccess;
1252  }
1253 
1254  return *this;
1255 }
1256 
1257 template<typename DataType, bool isFundamental, bool isSerializable>
1259  DataType,
1260  isFundamental,
1261  isSerializable
1262 >& AbstractProperty<
1263  DataType,
1264  isFundamental,
1265  isSerializable
1266 >::operator=(
1267  AbstractProperty &&rhs
1268 ){
1269  if(this != &rhs){
1270  indexDescriptor = std::move(rhs.indexDescriptor);
1271 
1272  blockSize = rhs.blockSize;
1273 
1274  data = rhs.data;
1275 
1276  allowIndexOutOfBoundsAccess = rhs.allowIndexOutOfBoundsAccess;
1277  }
1278 
1279  return *this;
1280 }
1281 
1282 template<typename DataType, bool isFundamental, bool isSerializable>
1283 void AbstractProperty<
1284  DataType,
1285  isFundamental,
1286  isSerializable
1287 >::calculateDynamically(const Index &index, DataType *block){
1288  TBTKExit(
1289  "AbstractProperty::calculateDynamically()",
1290  "This Property does not support dynamic calculation.",
1291  ""
1292  );
1293 }
1294 
1295 }; //End namespace Property
1296 }; //End namespace TBTK
1297 
1298 #endif
static std::string extract(const std::string &serialization, Mode mode, std::string component)
unsigned int getSize() const
void setDefaultValue(const DataType &defaultValue)
Definition: AbstractProperty.h:629
void setAllowIndexOutOfBoundsAccess(bool allowIndexOutOfBoundsAccess)
Definition: AbstractProperty.h:620
virtual ~AbstractProperty()
Definition: AbstractProperty.h:1229
Describes the index structure of data stored for several indices.
Definition: IndexDescriptor.h:39
Precompiler macros.
std::vector< DataType > & getDataRW()
Definition: AbstractProperty.h:468
Definition: Serializable.h:40
bool contains(const Index &index) const
Definition: AbstractProperty.h:519
virtual std::string serialize(Mode mode) const
const IndexDescriptor & getIndexDescriptor() const
Definition: AbstractProperty.h:509
std::vector< int > getRanges() const
Definition: AbstractProperty.h:486
std::vector< int > getRanges() const
Definition: IndexDescriptor.h:255
void setRanges(const int *ranges, unsigned int dimensions)
Definition: IndexDescriptor.h:239
const std::vector< DataType > & getData() const
Definition: AbstractProperty.h:459
virtual const DataType & operator()(const Index &index, unsigned int offset=0) const
Definition: AbstractProperty.h:530
virtual std::string serialize(Mode mode) const
unsigned int getBlockSize() const
Definition: AbstractProperty.h:441
Describes the index structure of data stored for several indices.
Abstract Property class.
Definition: AbstractProperty.h:95
unsigned int getSize() const
Definition: AbstractProperty.h:450
bool getLinearMapIsGenerated() const
Definition: IndexTree.h:378
Data structure for mapping physical indices to linear indices.
Definition: IndexTree.h:34
Flexible physical index.
Definition: Index.h:69
Definition: ModelFactory.h:35
unsigned int getDimensions() const
Definition: IndexDescriptor.h:229
AbstractProperty()
Definition: AbstractProperty.h:840
AbstractProperty & operator=(const AbstractProperty &abstractProperty)
Definition: AbstractProperty.h:1241
static void deserialize(const std::string &serialization, bool *b, Mode mode)
Definition: Serializable.h:196
int getLinearIndex(const Index &index, bool returnNegativeForMissingIndex=false) const
Definition: IndexDescriptor.h:316
Mode
Definition: Serializable.h:44
static bool validate(const std::string &serialization, const std::string &id, Mode mode)
virtual std::string serialize(Mode mode) const =0
unsigned int getDimensions() const
Definition: AbstractProperty.h:477
void setIndexTree(const IndexTree &indexTree)
bool contains(const Index &index) const
Definition: IndexDescriptor.h:373
int getOffset(const Index &index) const
Definition: AbstractProperty.h:495