00001 #ifndef PROTON_VALUE_HPP
00002 #define PROTON_VALUE_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "./codec/encoder.hpp"
00026 #include "./codec/decoder.hpp"
00027 #include "./internal/type_traits.hpp"
00028 #include "./scalar.hpp"
00029 #include "./types_fwd.hpp"
00030
00031 #include <iosfwd>
00032
00033 namespace proton {
00034
00035 namespace internal {
00036
00038 class value_base {
00039 public:
00041 PN_CPP_EXTERN type_id type() const;
00042
00044 PN_CPP_EXTERN bool empty() const;
00045
00046 protected:
00047 internal::data& data();
00048 internal::data data_;
00049
00050 friend class value_ref;
00051 friend class codec::encoder;
00052 friend class codec::decoder;
00053 };
00054
00055 }
00056
00060 class value : public internal::value_base, private internal::comparable<value> {
00061 private:
00062
00063 template<class T, class U=void> struct assignable :
00064 public internal::enable_if<codec::is_encodable<T>::value, U> {};
00065 template<class U> struct assignable<value, U> {};
00066
00067 public:
00069 PN_CPP_EXTERN value();
00070
00073 PN_CPP_EXTERN value(const value&);
00074 PN_CPP_EXTERN value& operator=(const value&);
00075 #if PN_CPP_HAS_RVALUE_REFERENCES
00076 PN_CPP_EXTERN value(value&&);
00077 PN_CPP_EXTERN value& operator=(value&&);
00078 #endif
00080
00082 template <class T> value(const T& x, typename assignable<T>::type* = 0) { *this = x; }
00083
00085 template <class T> typename assignable<T, value&>::type operator=(const T& x) {
00086 codec::encoder e(*this);
00087 e << x;
00088 return *this;
00089 }
00090
00092 PN_CPP_EXTERN void clear();
00093
00095 template<class T> void get(T &t) const;
00096 template<class T> T get() const;
00097 PN_CPP_EXTERN int64_t as_int() const;
00098 PN_CPP_EXTERN uint64_t as_uint() const;
00099 PN_CPP_EXTERN double as_double() const;
00100 PN_CPP_EXTERN std::string as_string() const;
00102
00104 friend PN_CPP_EXTERN void swap(value&, value&);
00105
00108 friend PN_CPP_EXTERN bool operator==(const value& x, const value& y);
00109 friend PN_CPP_EXTERN bool operator<(const value& x, const value& y);
00111
00112 friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const value&);
00113 };
00114
00115 namespace internal {
00116
00117
00118
00119
00120
00121
00122
00123
00124 class value_ref : public value {
00125 public:
00126 value_ref(pn_data_t* = 0);
00127 value_ref(const internal::data&);
00128 value_ref(const value_base&);
00129
00130
00131 void refer(pn_data_t*);
00132 void refer(const internal::data&);
00133 void refer(const value_base&);
00134
00135
00136 void reset();
00137
00138
00139 template <class T> value_ref& operator=(const T& x) {
00140 static_cast<value&>(*this) = x;
00141 return *this;
00142 }
00143 };
00144
00145 }
00146
00147
00150 template<class T> T get(const value& v) { T x; get(v, x); return x; }
00151
00157 template<class T> void get(const value& v, T& x) { codec::decoder d(v, true); d >> x; }
00158
00161 template<class T> T coerce(const value& v) { T x; coerce(v, x); return x; }
00162
00168 template<class T> void coerce(const value& v, T& x) {
00169 codec::decoder d(v, false);
00170 if (type_id_is_scalar(v.type())) {
00171 scalar s;
00172 d >> s;
00173 x = internal::coerce<T>(s);
00174 } else {
00175 d >> x;
00176 }
00177 }
00178
00180 template<> inline void get<null>(const value& v, null&) {
00181 assert_type_equal(NULL_TYPE, v.type());
00182 }
00183
00185 PN_CPP_EXTERN std::string to_string(const value& x);
00186
00188 template<class T> void value::get(T &x) const { x = proton::get<T>(*this); }
00189 template<class T> T value::get() const { return proton::get<T>(*this); }
00190 inline int64_t value::as_int() const { return proton::coerce<int64_t>(*this); }
00191 inline uint64_t value::as_uint() const { return proton::coerce<uint64_t>(*this); }
00192 inline double value::as_double() const { return proton::coerce<double>(*this); }
00193 inline std::string value::as_string() const { return proton::coerce<std::string>(*this); }
00195
00196 }
00197
00198 #endif // PROTON_VALUE_HPP