1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
#ifndef PROTON_VALUE_HPP
#define PROTON_VALUE_HPP
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
#include "./codec/encoder.hpp"
#include "./codec/decoder.hpp"
#include "./internal/type_traits.hpp"
#include "./scalar.hpp"
#include "./types_fwd.hpp"
#include <proton/type_compat.h>
#include <iosfwd>
/// @file
/// @copybrief proton::value
namespace proton {
namespace internal {
// Separate value data from implicit conversion constructors to avoid template recursion.
class value_base {
protected:
internal::data& data();
internal::data data_;
friend class codec::encoder;
friend class codec::decoder;
};
} // internal
/// A holder for any AMQP value, simple or complex.
///
/// @see @ref types_page
class value : public internal::value_base, private internal::comparable<value> {
private:
// Enabler for encodable types excluding proton::value.
template<class T, class U=void> struct assignable :
public std::enable_if<codec::is_encodable<T>::value, U> {};
template<class U> struct assignable<value, U> {};
public:
/// Create a null value
PN_CPP_EXTERN value();
/// @name Copy a value
/// @{
PN_CPP_EXTERN value(const value&);
PN_CPP_EXTERN value& operator=(const value&);
PN_CPP_EXTERN value(value&&);
PN_CPP_EXTERN value& operator=(value&&);
/// @}
/// Copy from any allowed type T.
template <class T> value(const T& x, typename assignable<T>::type* = 0) { *this = x; }
/// Assign from any allowed type T.
template <class T> typename assignable<T, value&>::type operator=(const T& x) {
codec::encoder e(*this);
e << x;
return *this;
}
/// Get the type ID for the current value.
PN_CPP_EXTERN type_id type() const;
/// True if the value is null
PN_CPP_EXTERN bool empty() const;
/// Reset the value to null/empty
PN_CPP_EXTERN void clear();
/// @cond INTERNAL
template<class T> PN_CPP_DEPRECATED("Use 'proton::get'") void get(T &t) const;
template<class T> PN_CPP_DEPRECATED("Use 'proton::get'") T get() const;
/// @endcond
/// swap values
friend PN_CPP_EXTERN void swap(value&, value&);
/// @name Comparison operators
/// @{
friend PN_CPP_EXTERN bool operator==(const value& x, const value& y);
friend PN_CPP_EXTERN bool operator<(const value& x, const value& y);
///@}
/// If contained value is a scalar type T, print using operator<<(T)
///
/// Complex types are printed in a non-standard human-readable format but
/// that may change in future so should not be parsed.
friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const value&);
///@cond INTERNAL
/// Used to refer to existing pn_data_t* values as proton::value
value(pn_data_t* d); // Refer to existing pn_data_t
void reset(pn_data_t* d = 0); // Refer to a new pn_data_t
///@endcond
};
/// @copydoc scalar::get
/// @relatedalso proton::value
template<class T> T get(const value& v) { T x; get(v, x); return x; }
/// Like get(const value&) but extracts the value to a reference @p x
/// instead of returning it. May be more efficient for complex values
/// (arrays, maps, etc.)
///
/// @relatedalso proton::value
template<class T> void get(const value& v, T& x) { codec::decoder d(v, true); d >> x; }
/// @relatedalso proton::value
template<class T, class U> inline void get(const U& u, T& x) { const value v(u); get(v, x); }
/// @copydoc scalar::coerce
/// @relatedalso proton::value
template<class T> T coerce(const value& v) { T x; coerce(v, x); return x; }
/// Like coerce(const value&) but assigns the value to a reference
/// instead of returning it. May be more efficient for complex values
/// (arrays, maps, etc.)
///
/// @relatedalso proton::value
template<class T> void coerce(const value& v, T& x) {
codec::decoder d(v, false);
scalar s;
if (type_id_is_scalar(v.type())) {
d >> s;
x = internal::coerce<T>(s);
} else {
d >> x;
}
}
/// Special case for null, just checks that value contains NULL.
template<> inline void get<null>(const value& v, null&) {
assert_type_equal(NULL_TYPE, v.type());
}
/// @copybrief get<null>()
template<> inline void get<decltype(nullptr)>(const value& v, decltype(nullptr)&) {
assert_type_equal(NULL_TYPE, v.type());
}
/// Return a readable string representation of x for display purposes.
PN_CPP_EXTERN std::string to_string(const value& x);
/// @cond INTERNAL
template<class T> void value::get(T &x) const { x = proton::get<T>(*this); }
template<class T> T value::get() const { return proton::get<T>(*this); }
/// @endcond
} // proton
#endif // PROTON_VALUE_HPP
|