proton/scalar_base.hpp

Go to the documentation of this file.
00001 #ifndef PROTON_SCALAR_BASE_HPP
00002 #define PROTON_SCALAR_BASE_HPP
00003 
00004 /*
00005  *
00006  * Licensed to the Apache Software Foundation (ASF) under one
00007  * or more contributor license agreements.  See the NOTICE file
00008  * distributed with this work for additional information
00009  * regarding copyright ownership.  The ASF licenses this file
00010  * to you under the Apache License, Version 2.0 (the
00011  * "License"); you may not use this file except in compliance
00012  * with the License.  You may obtain a copy of the License at
00013  *
00014  *   http://www.apache.org/licenses/LICENSE-2.0
00015  *
00016  * Unless required by applicable law or agreed to in writing,
00017  * software distributed under the License is distributed on an
00018  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
00019  * KIND, either express or implied.  See the License for the
00020  * specific language governing permissions and limitations
00021  * under the License.
00022  *
00023  */
00024 
00025 #include "./binary.hpp"
00026 #include "./decimal.hpp"
00027 #include "./error.hpp"
00028 #include "./internal/comparable.hpp"
00029 #include "./internal/export.hpp"
00030 #include "./internal/type_traits.hpp"
00031 #include "./symbol.hpp"
00032 #include "./timestamp.hpp"
00033 #include "./type_id.hpp"
00034 #include "./types_fwd.hpp"
00035 #include "./uuid.hpp"
00036 
00037 #include <proton/type_compat.h>
00038 
00039 #include <iosfwd>
00040 #include <string>
00041 #include <typeinfo>
00042 
00045 
00046 namespace proton {
00047 
00048 class scalar_base;
00049 
00050 namespace codec {
00051 class decoder;
00052 class encoder;
00053 }
00054 
00055 namespace internal {
00056 template<class T> T get(const scalar_base& s);
00057 }
00058 
00060 class scalar_base : private internal::comparable<scalar_base> {
00061   public:
00063     PN_CPP_EXTERN type_id type() const;
00064 
00066     PN_CPP_EXTERN bool empty() const;
00067 
00069   friend PN_CPP_EXTERN bool operator<(const scalar_base& x, const scalar_base& y);
00071   friend PN_CPP_EXTERN bool operator==(const scalar_base& x, const scalar_base& y);
00073   friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream& o, const scalar_base& x);
00074 
00075   protected:
00076     PN_CPP_EXTERN scalar_base(const pn_atom_t& a);
00077     PN_CPP_EXTERN scalar_base();
00078     PN_CPP_EXTERN scalar_base(const scalar_base&);
00079     PN_CPP_EXTERN scalar_base& operator=(const scalar_base&);
00080 
00081     PN_CPP_EXTERN void put_(bool);
00082     PN_CPP_EXTERN void put_(uint8_t);
00083     PN_CPP_EXTERN void put_(int8_t);
00084     PN_CPP_EXTERN void put_(uint16_t);
00085     PN_CPP_EXTERN void put_(int16_t);
00086     PN_CPP_EXTERN void put_(uint32_t);
00087     PN_CPP_EXTERN void put_(int32_t);
00088     PN_CPP_EXTERN void put_(uint64_t);
00089     PN_CPP_EXTERN void put_(int64_t);
00090     PN_CPP_EXTERN void put_(wchar_t);
00091     PN_CPP_EXTERN void put_(float);
00092     PN_CPP_EXTERN void put_(double);
00093     PN_CPP_EXTERN void put_(timestamp);
00094     PN_CPP_EXTERN void put_(const decimal32&);
00095     PN_CPP_EXTERN void put_(const decimal64&);
00096     PN_CPP_EXTERN void put_(const decimal128&);
00097     PN_CPP_EXTERN void put_(const uuid&);
00098     PN_CPP_EXTERN void put_(const std::string&);
00099     PN_CPP_EXTERN void put_(const symbol&);
00100     PN_CPP_EXTERN void put_(const binary&);
00101     PN_CPP_EXTERN void put_(const char* s); 
00102     PN_CPP_EXTERN void put_(const null&);
00103 #if PN_CPP_HAS_NULLPTR
00104     PN_CPP_EXTERN void put_(decltype(nullptr));
00105 #endif
00106 
00107     template<class T> void put(const T& x) { putter<T>::put(*this, x); }
00108 
00109   private:
00110     PN_CPP_EXTERN void get_(bool&) const;
00111     PN_CPP_EXTERN void get_(uint8_t&) const;
00112     PN_CPP_EXTERN void get_(int8_t&) const;
00113     PN_CPP_EXTERN void get_(uint16_t&) const;
00114     PN_CPP_EXTERN void get_(int16_t&) const;
00115     PN_CPP_EXTERN void get_(uint32_t&) const;
00116     PN_CPP_EXTERN void get_(int32_t&) const;
00117     PN_CPP_EXTERN void get_(uint64_t&) const;
00118     PN_CPP_EXTERN void get_(int64_t&) const;
00119     PN_CPP_EXTERN void get_(wchar_t&) const;
00120     PN_CPP_EXTERN void get_(float&) const;
00121     PN_CPP_EXTERN void get_(double&) const;
00122     PN_CPP_EXTERN void get_(timestamp&) const;
00123     PN_CPP_EXTERN void get_(decimal32&) const;
00124     PN_CPP_EXTERN void get_(decimal64&) const;
00125     PN_CPP_EXTERN void get_(decimal128&) const;
00126     PN_CPP_EXTERN void get_(uuid&) const;
00127     PN_CPP_EXTERN void get_(std::string&) const;
00128     PN_CPP_EXTERN void get_(symbol&) const;
00129     PN_CPP_EXTERN void get_(binary&) const;
00130     PN_CPP_EXTERN void get_(null&) const;
00131 #if PN_CPP_HAS_NULLPTR
00132     PN_CPP_EXTERN void get_(decltype(nullptr)&) const;
00133 #endif
00134 
00135 
00136     // use template structs, functions cannot be  partially specialized.
00137     template <class T, class Enable=void> struct putter {
00138         static void put(scalar_base& s, const T& x) { s.put_(x); }
00139     };
00140     template <class T>
00141     struct putter<T, typename internal::enable_if<internal::is_unknown_integer<T>::value>::type> {
00142         static void put(scalar_base& s, const T& x) {
00143             s.put_(static_cast<typename internal::known_integer<T>::type>(x));
00144         }
00145     };
00146     template <class T, class Enable=void>
00147     struct getter {
00148         static T get(const scalar_base& s) { T x; s.get_(x); return x; }
00149     };
00150     template <class T>
00151     struct getter<T, typename internal::enable_if<internal::is_unknown_integer<T>::value>::type> {
00152         static T get(const scalar_base& s) {
00153             typename internal::known_integer<T>::type x; s.get_(x); return x;
00154         }
00155     };
00156 
00157     void ok(pn_type_t) const;
00158     void set(const pn_atom_t&);
00159     void set(const binary& x, pn_type_t t);
00160 
00161     pn_atom_t atom_;
00162     binary bytes_; // Hold binary data.
00163 
00165   friend class message;
00166   friend class codec::encoder;
00167   friend class codec::decoder;
00168   template<class T> friend T internal::get(const scalar_base& s);
00170 };
00171 
00172 namespace internal {
00173 
00174 template<class T> T get(const scalar_base& s) {
00175       return scalar_base::getter<T>::get(s);
00176 }
00177 
00178 template <class R, class F> R visit(const scalar_base& s, F f) {
00179     switch(s.type()) {
00180       case BOOLEAN: return f(internal::get<bool>(s));
00181       case UBYTE: return f(internal::get<uint8_t>(s));
00182       case BYTE: return f(internal::get<int8_t>(s));
00183       case USHORT: return f(internal::get<uint16_t>(s));
00184       case SHORT: return f(internal::get<int16_t>(s));
00185       case UINT: return f(internal::get<uint32_t>(s));
00186       case INT: return f(internal::get<int32_t>(s));
00187       case CHAR: return f(internal::get<wchar_t>(s));
00188       case ULONG: return f(internal::get<uint64_t>(s));
00189       case LONG: return f(internal::get<int64_t>(s));
00190       case TIMESTAMP: return f(internal::get<timestamp>(s));
00191       case FLOAT: return f(internal::get<float>(s));
00192       case DOUBLE: return f(internal::get<double>(s));
00193       case DECIMAL32: return f(internal::get<decimal32>(s));
00194       case DECIMAL64: return f(internal::get<decimal64>(s));
00195       case DECIMAL128: return f(internal::get<decimal128>(s));
00196       case UUID: return f(internal::get<uuid>(s));
00197       case BINARY: return f(internal::get<binary>(s));
00198       case STRING: return f(internal::get<std::string>(s));
00199       case SYMBOL: return f(internal::get<symbol>(s));
00200       default: throw conversion_error("invalid scalar type "+type_name(s.type()));
00201     }
00202 }
00203 
00204 PN_CPP_EXTERN conversion_error make_coercion_error(const char* cpp_type, type_id amqp_type);
00205 
00206 template<class T> struct coerce_op {
00207     template <class U>
00208     typename enable_if<is_convertible<U, T>::value, T>::type operator()(const U& x) {
00209         return static_cast<T>(x);
00210     }
00211     template <class U>
00212     typename enable_if<!is_convertible<U, T>::value, T>::type operator()(const U&) {
00213         throw make_coercion_error(typeid(T).name(), type_id_of<U>::value);
00214     }
00215 };
00216 
00217 template <class T> T coerce(const scalar_base& s) { return visit<T>(s, coerce_op<T>()); }
00218 } // namespace internal
00219 
00221 PN_CPP_EXTERN std::string to_string(const scalar_base& x);
00222 
00223 } // proton
00224 
00225 #endif // PROTON_SCALAR_BASE_HPP

Generated on 30 Jul 2020 for Qpid Proton C++ by  doxygen 1.6.1