3
0
mirror of https://github.com/triqs/dft_tools synced 2024-11-01 11:43:47 +01:00
dft_tools/triqs/parameters/_field.cpp
Olivier Parcollet af084f5d59 parameters & wrapper
- new parameter class :
  parameters are viewed as form, built in C++, and filled in C++/python.
  Each field of the form as a precise C++ type (erased using standard techniques).
  First tests ok, to be reread/checked.

  TODO : serialization is commented. Lead to long compilation time & large code
  due to boost::serialization. Use h5 when possible.

- wrapper :
  - separated the converters of the wrapped type in the TRIQS library
  - necessary for parameters (it used outside an .so) and potentially
    other codes, outside an .so module
2014-05-19 15:19:18 +02:00

84 lines
2.8 KiB
C++

#include "./_field.hpp"
#include <boost/lexical_cast.hpp>
namespace triqs {
namespace params {
std::map<std::type_index, std::string> _field::type_names;
std::string _field::type_name(std::type_index i) {
try {
return type_names.at(i);
}
catch (...) {
return i.name();
}
}
//-----------------------------------------------------------------------
void h5_write(h5::group g, std::string const &name, _field const &obj) {
obj.p->h5_write_(g, name);
};
//-----------------------------------------------------------------------
void h5_read(h5::group g, std::string const &name, _field &obj) {
obj.p->h5_read_(g, name);
obj.modified = true;
};
template <typename T> T lex_cast_from_string(_field const &obj) {
std::string s = extract<std::string>(obj);
try {
return boost::lexical_cast<T>(s);
}
catch (boost::bad_lexical_cast &) {
TRIQS_RUNTIME_ERROR << " extraction : can not read the string " << s << " into a " << typeid(T).name();
}
}
//-----------------------------------------------------
template <> // specialize for double since we can make int -> double conversion
double extract(_field const &obj) {
if (obj.has_type<double>()) return *static_cast<const double *>(obj.get());
if (obj.has_type<std::string>()) {
return lex_cast_from_string<double>(obj);
}
#define TRANSFORM_TYPE(T) \
if (obj.has_type<T>()) return extract<T>(obj)
TRANSFORM_TYPE(int);
// TRANSFORM_TYPE(unsigned int);
TRANSFORM_TYPE(long);
// TRANSFORM_TYPE(unsigned long);
TRANSFORM_TYPE(short);
// TRANSFORM_TYPE(unsigned short);
TRANSFORM_TYPE(long long);
// TRANSFORM_TYPE(unsigned long long);
// TRANSFORM_TYPE(float);
#undef TRANSFORM_TYPE
TRIQS_RUNTIME_ERROR << "extraction of " << obj.name() << " impossible : type mismatch. Got " << obj.type_name()
<< ", while I am supposed to extract a double";
}
//-----------------------------------------------------
template <> // specialize for double since we can make int -> double conversion
long extract(_field const &obj) {
if (obj.has_type<long>()) return *static_cast<const long *>(obj.get());
if (obj.has_type<std::string>()) {
return lex_cast_from_string<long>(obj);
}
TRIQS_RUNTIME_ERROR << "extraction of " << obj.name() << " impossible : type mismatch. Got " << obj.type_name()
<< ", while I am supposed to extract a double";
}
// --------------- _field cast op implementation ---------------------------------------
#define CAST_OPERATOR(r, data, T) \
_field::operator T() const { return extract<T>(*this); }
BOOST_PP_SEQ_FOR_EACH(CAST_OPERATOR, nil, TRIQS_UTIL_OPAQUE_OBJECT_PREDEFINED_CAST);
#undef CAST_OPERATOR
}
}