ALPSCore reference
dict_value.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
9 /* Requirements for the `dict_value_type`:
10 
11  1. It can hold a value from a predefined set of scalar types, of
12  corresponding vector types, or can be in the "undefined" ("empty") state.
13 
14  2. Any value can be assigned to it; the object acquires both the
15  type and the value, if it is convertible to one of the
16  supported types. The value is converted to a "larger" supported
17  type.
18  Special case 1: conversion from char is unspecified.
19  Special case 2: conversion from char* to string is supported.
20 
21  3. If "undefined", it cannot be assigned to anything.
22 
23  4. If holds a value of some type, it can be assigned to the same or a "larger" type.
24  Special case 1: conversion to char is unspecified (may throw).
25  Special case 2: conversion to char* is explicitly unsupported, even for strings
26  (the user can use `const char* p=val.as<string>().c_str()` and face the consequences).
27 
28  5. It holds its name for error reporting purposes.
29 
30  6. It can be streamed to an HDF5 archive member.
31 
32  7. It can be broadcast over MPI.
33 
34  8. It can be streamed to an `ostream`.
35 */
36 
37 #ifndef ALPS_PARAMS_DICT_VALUE_HPP_a8ecbead92aa4a1995f43adfc6d0aae0
38 #define ALPS_PARAMS_DICT_VALUE_HPP_a8ecbead92aa4a1995f43adfc6d0aae0
39 
40 #include <iosfwd>
41 #include <type_traits>
42 #include <stdexcept>
43 
44 #include <boost/variant/variant.hpp>
45 
46 #include "./dict_exceptions.hpp"
47 #include "./dict_types.hpp" // Sequences of supported types
48 
49 #include <alps/hdf5/archive.hpp>
50 
51 #ifdef ALPS_HAVE_MPI
52 #include <alps/utilities/mpi.hpp>
53 #endif
54 
55 namespace alps {
56  namespace params_ns {
57 
58  namespace detail {
59  template <typename> struct is_allowed;
60  }
61 
62  class dict_value {
63  public:
64 
65  typedef boost::make_variant_over<detail::dict_all_types>::type value_type;
66  typedef detail::None None;
67 
68  private:
69  std::string name_;
70  value_type val_;
71 
72  public:
73 
75  // FIXME: This is used only for MPI and must be changed
76  dict_value(): name_("NO_NAME"), val_() {}
77 
79  explicit dict_value(const std::string& name): name_(name), val_() {}
80 
82  bool empty() const;
83 
85  template <typename X>
86  bool isType() const;
87 
89  template <typename T>
90  const T& operator=(const T& rhs);
91 
93  const char* operator=(const char* rhs);
94 
96  template <typename T>
97  T as() const;
98 
100  template <typename T
101 #ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
102  ,typename std::enable_if<detail::is_allowed<T>::value, int>::type =0
103 #endif
104  >
105  inline operator T() const {
106  // BOOST_STATIC_ASSERT_MSG(detail::is_allowed<T>::value, "The type is not supported by the dictionary");
107  return as<T>();
108  }
109 
110  // template <typename T, int>
111  // operator T() const;
112 
114  void clear();
115 
117 
120  template <typename T>
121  int compare(const T& rhs) const;
122 
123  int compare(const dict_value& rhs) const;
124 
126  bool equals(const dict_value& rhs) const;
127 
129  void save(alps::hdf5::archive& ar) const;
130 
132  void load(alps::hdf5::archive& ar);
133 
135 
139  template <typename F>
140  typename F::result_type apply_visitor(F& visitor) const;
141 
143 
147  template <typename F>
148  typename F::result_type apply_visitor(const F& visitor) const;
149 
151  friend
152  std::ostream& print(std::ostream&, const dict_value&, bool terse);
153 
154 #ifdef ALPS_HAVE_MPI
155  void broadcast(const alps::mpi::communicator& comm, int root);
156 #endif
157  };
158 
160  inline std::ostream& operator<<(std::ostream& os, const dict_value& dv) {
161  return print(os, dv, false);
162  }
163 
164  } // params_ns::
165 } // alps::
166 
167 #include "./dict_value_impl.hpp"
168 
169 #endif /* ALPS_PARAMS_DICT_VALUE_HPP_a8ecbead92aa4a1995f43adfc6d0aae0 */
dict_value()
Constructs the empty nameless value.
Definition: dict_value.hpp:76
void load(archive &ar, std::string const &path, T &value, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
Definition: archive.hpp:309
void broadcast(C const &c, P &p, int r=0)
Definition: api.hpp:56
Header for object-oriented interface to MPI (similar to boost::mpi)
Encapsulation of an MPI communicator and some communicator-related operations.
Definition: mpi.hpp:111
F::result_type apply_visitor(F &visitor, dictionary::const_iterator it)
Const-access visitor to a value by an iterator.
Definition: dictionary.hpp:110
std::ostream & print(std::ostream &s, const dict_value &dv, bool terse)
Definition: dict_value.cpp:186
boost::make_variant_over< detail::dict_all_types >::type value_type
Definition: dict_value.hpp:65
dict_value(const std::string &name)
Constructs the empty value.
Definition: dict_value.hpp:79
std::ostream & operator<<(std::ostream &os, const dict_value &dv)
Print the value together with type in some human-readable format.
Definition: dict_value.hpp:160
detail::None None
"Empty value" type
Definition: dict_value.hpp:66
void save(archive &ar, std::string const &path, T const &value, std::vector< std::size_t >=std::vector< std::size_t >(), std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
Definition: archive.hpp:292