blob: 4149f60b91fc1084091c54139b5baaa8fd804b18 [file] [log] [blame]
* 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
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* 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 <iosfwd>
namespace proton {
class message;
namespace internal {
class value_base;
PN_CPP_EXTERN std::ostream& operator<<(std::ostream& o, const value_base& x);
/// Separate value data from implicit conversion constructors to avoid
/// recursions.
class value_base {
/// 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;
codec::data& data() const;
mutable class codec::data data_;
/// @cond INTERNAL
friend class proton::message;
friend class codec::encoder;
friend class codec::decoder;
friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const value_base&);
/// @endcond
} // internal
/// A holder for any AMQP value, simple or complex.
/// @see @ref types_page
class value : public internal::value_base, private internal::comparable<value> {
// Enabler for encodable types excluding proton::value.
template<class T, class U=void> struct assignable :
public internal::enable_if<codec::is_encodable<T>::value, U> {};
template<class U> struct assignable<value, U> {};
/// 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&&);
/// @}
/// Construct 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;
/// Reset the value to null
PN_CPP_EXTERN void clear();
/// @cond INTERNAL (deprecated)
template<class T> void get(T &t) const;
template<class T> T get() const;
PN_CPP_EXTERN int64_t as_int() const;
PN_CPP_EXTERN uint64_t as_uint() const;
PN_CPP_EXTERN double as_double() const;
PN_CPP_EXTERN std::string as_string() 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);
/// @}
/// @cond INTERNAL
PN_CPP_EXTERN explicit value(const codec::data&);
/// @endcond
/// @copydoc scalar::get
/// @related proton::value
template<class T> T get(const value& v) { T x; get(v, x); return x; }
/// Like get(const value&) but assigns the value to a reference
/// instead of returning it. May be more efficient for complex values
/// (arrays, maps, etc.)
/// @related proton::value
template<class T> void get(const value& v, T& x) { codec::decoder d(v, true); d >> x; }
/// @copydoc scalar::coerce
/// @related 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.)
/// @related proton::value
template<class T> void coerce(const value& v, T& x) {
codec::decoder d(v, false);
if (type_id_is_scalar(v.type())) {
scalar s;
d >> s;
x = internal::coerce<T>(s);
} else {
d >> x;
/// Special case for get<null>(), just checks that value contains NULL.
template<> inline void get<null>(const value& v, null&) { assert_type_equal(NULL_TYPE, v.type()); }
/// @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); }
inline int64_t value::as_int() const { return proton::coerce<int64_t>(*this); }
inline uint64_t value::as_uint() const { return proton::coerce<uint64_t>(*this); }
inline double value::as_double() const { return proton::coerce<double>(*this); }
inline std::string value::as_string() const { return proton::coerce<std::string>(*this); }
/// @endcond
} // proton