http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/connection.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/connection.hpp b/cpp/include/proton/connection.hpp new file mode 100644 index 0000000..603d5dd --- /dev/null +++ b/cpp/include/proton/connection.hpp @@ -0,0 +1,174 @@ +#ifndef PROTON_CONNECTION_HPP +#define PROTON_CONNECTION_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 "./fwd.hpp" +#include "./internal/export.hpp" +#include "./internal/object.hpp" +#include "./endpoint.hpp" +#include "./session.hpp" + +#include <proton/type_compat.h> + +#include <string> + +/// @file +/// @copybrief proton::connection + +struct pn_connection_t; + +namespace proton { + +/// A connection to a remote AMQP peer. +class +PN_CPP_CLASS_EXTERN connection : public internal::object<pn_connection_t>, public endpoint { + /// @cond INTERNAL + PN_CPP_EXTERN connection(pn_connection_t* c) : internal::object<pn_connection_t>(c) {} + /// @endcond + + public: + /// Create an empty connection. + connection() : internal::object<pn_connection_t>(0) {} + + PN_CPP_EXTERN bool uninitialized() const; + PN_CPP_EXTERN bool active() const; + PN_CPP_EXTERN bool closed() const; + + PN_CPP_EXTERN class error_condition error() const; + + /// Get the container. + /// + /// @throw proton::error if this connection is not managed by a + /// container + PN_CPP_EXTERN class container& container() const; + + /// Get the work_queue for the connection. + PN_CPP_EXTERN class work_queue& work_queue() const; + + /// Get the transport for the connection. + PN_CPP_EXTERN class transport transport() const; + + /// Return the AMQP hostname attribute for the connection. + PN_CPP_EXTERN std::string virtual_host() const; + + /// Return the container ID for the connection. + PN_CPP_EXTERN std::string container_id() const; + + /// Return authenticated user for the connection + /// Note: The value returned is not stable until the on_transport_open event is received + PN_CPP_EXTERN std::string user() const; + + /// Open the connection. + /// + /// @see endpoint_lifecycle + PN_CPP_EXTERN void open(); + + /// @copydoc open + PN_CPP_EXTERN void open(const connection_options&); + + PN_CPP_EXTERN void close(); + PN_CPP_EXTERN void close(const error_condition&); + + /// Open a new session. + PN_CPP_EXTERN session open_session(); + + /// @copydoc open_session + PN_CPP_EXTERN session open_session(const session_options&); + + /// Get the default session. A default session is created on the + /// first call and reused for the lifetime of the connection. + PN_CPP_EXTERN session default_session(); + + /// Open a sender for `addr` on default_session(). + PN_CPP_EXTERN sender open_sender(const std::string& addr); + + /// @copydoc open_sender + PN_CPP_EXTERN sender open_sender(const std::string& addr, const sender_options&); + + /// Open a receiver for `addr` on default_session(). + PN_CPP_EXTERN receiver open_receiver(const std::string& addr); + + /// @copydoc open_receiver + PN_CPP_EXTERN receiver open_receiver(const std::string& addr, + const receiver_options&); + + /// @see proton::container::sender_options() + PN_CPP_EXTERN class sender_options sender_options() const; + + /// @see container::receiver_options() + PN_CPP_EXTERN class receiver_options receiver_options() const; + + /// Return all sessions on this connection. + PN_CPP_EXTERN session_range sessions() const; + + /// Return all receivers on this connection. + PN_CPP_EXTERN receiver_range receivers() const; + + /// Return all senders on this connection. + PN_CPP_EXTERN sender_range senders() const; + + /// Get the maximum frame size allowed by the remote peer. + /// + /// @see @ref connection_options::max_frame_size + PN_CPP_EXTERN uint32_t max_frame_size() const; + + /// Get the maximum number of open sessions allowed by the remote + /// peer. + /// + /// @see @ref connection_options::max_sessions + PN_CPP_EXTERN uint16_t max_sessions() const; + + /// Get the idle timeout set by the remote peer. + /// + /// @see @ref connection_options::idle_timeout + PN_CPP_EXTERN uint32_t idle_timeout() const; + + /// **Unsettled API** - Trigger an event from another thread. + /// + /// This method can be called from any thread. The Proton library + /// will call `messaging_handler::on_connection_wake()` as soon as + /// possible in the correct event-handling thread. + /// + /// **Thread-safety** - This is the *only* `proton::connection` + /// function that can be called from outside the handler thread. + /// + /// @note Spurious `messaging_handler::on_connection_wake()` calls + /// can occur even if the application does not call `wake()`. + /// + /// @note Multiple calls to `wake()` may be coalesced into a + /// single call to `messaging_handler::on_connection_wake()` that + /// occurs after all of them. + /// + /// The `proton::work_queue` interface provides an easier way + /// execute code safely in the event-handler thread. + PN_CPP_EXTERN void wake() const; + + /// @cond INTERNAL + friend class internal::factory<connection>; + friend class container; + /// @endcond +}; + +} // proton + +#endif // PROTON_CONNECTION_HPP
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/connection_options.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/connection_options.hpp b/cpp/include/proton/connection_options.hpp new file mode 100644 index 0000000..2583a16 --- /dev/null +++ b/cpp/include/proton/connection_options.hpp @@ -0,0 +1,178 @@ +#ifndef PROTON_CONNECTION_OPTIONS_H +#define PROTON_CONNECTION_OPTIONS_H + +/* + * + * 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 "./duration.hpp" +#include "./fwd.hpp" +#include "./internal/config.hpp" +#include "./internal/export.hpp" +#include "./internal/pn_unique_ptr.hpp" +#include "./types_fwd.hpp" + +#include <proton/type_compat.h> + +#include <vector> +#include <string> + +/// @file +/// @copybrief proton::connection_options + +struct pn_connection_t; +struct pn_transport_t; + +namespace proton { + +/// Options for creating a connection. +/// +/// Options can be "chained" like this: +/// +/// @code +/// c = container.connect(url, connection_options().handler(h).max_frame_size(1234)); +/// @endcode +/// +/// You can also create an options object with common settings and use +/// it as a base for different connections that have mostly the same +/// settings: +/// +/// @code +/// connection_options opts; +/// opts.idle_timeout(1000).max_frame_size(10000); +/// c1 = container.connect(url1, opts.handler(h1)); +/// c2 = container.connect(url2, opts.handler(h2)); +/// @endcode +/// +/// Normal value semantics: copy or assign creates a separate copy of +/// the options. +class connection_options { + public: + /// Create an empty set of options. + PN_CPP_EXTERN connection_options(); + + /// Shorthand for `connection_options().handler(h)`. + PN_CPP_EXTERN connection_options(class messaging_handler& h); + + /// Copy options. + PN_CPP_EXTERN connection_options(const connection_options&); + + PN_CPP_EXTERN ~connection_options(); + + /// Copy options. + PN_CPP_EXTERN connection_options& operator=(const connection_options&); + + // XXX add C++11 move operations - Still relevant, and applies to all options + + /// Set a connection handler. + /// + /// The handler must not be deleted until + /// messaging_handler::on_transport_close() is called. + PN_CPP_EXTERN connection_options& handler(class messaging_handler&); + + /// Set the maximum frame size. It is unlimited by default. + PN_CPP_EXTERN connection_options& max_frame_size(uint32_t max); + + /// Set the maximum number of open sessions. The default is 32767. + PN_CPP_EXTERN connection_options& max_sessions(uint16_t max); + + /// Set the idle timeout. The default is no timeout. + /// + /// If set, the local peer will disconnect if it receives no AMQP + /// frames for an interval longer than `duration`. Also known as + /// "heartbeating", this is a way to detect dead peers even in the + /// presence of a live TCP connection. + PN_CPP_EXTERN connection_options& idle_timeout(duration); + + /// Set the container ID. + PN_CPP_EXTERN connection_options& container_id(const std::string& id); + + /// Set the virtual host name for the connection. For client + /// connections, it defaults to the host name used to set up the + /// connection. For server connections, it is unset by default. + /// + /// If making a client connection by SSL/TLS, this name is also + /// used for certificate verification and Server Name Indication. + PN_CPP_EXTERN connection_options& virtual_host(const std::string& name); + + /// Set the user name used to authenticate the connection. It is + /// unset by default. + /// + /// This value overrides any user name that is specified in the + /// URL used for `container::connect`. It is ignored if the + /// connection is created by `container::listen` because a + /// listening connection's identity is provided by the remote + /// client. + PN_CPP_EXTERN connection_options& user(const std::string&); + + /// Set the password used to authenticate the connection. + /// + /// This value is ignored if the connection is created by + /// `container::listen`. + PN_CPP_EXTERN connection_options& password(const std::string&); + + /// Set SSL client options. + PN_CPP_EXTERN connection_options& ssl_client_options(const class ssl_client_options&); + + /// Set SSL server options. + PN_CPP_EXTERN connection_options& ssl_server_options(const class ssl_server_options&); + + /// Enable or disable SASL. + PN_CPP_EXTERN connection_options& sasl_enabled(bool); + + /// Force the enabling of SASL mechanisms that disclose cleartext + /// passwords over the connection. By default, such mechanisms + /// are disabled. + PN_CPP_EXTERN connection_options& sasl_allow_insecure_mechs(bool); + + /// Specify the allowed mechanisms for use on the connection. + PN_CPP_EXTERN connection_options& sasl_allowed_mechs(const std::string&); + + /// **Unsettled API** - Set the SASL configuration name. + PN_CPP_EXTERN connection_options& sasl_config_name(const std::string&); + + /// **Unsettled API** - Set the SASL configuration path. + PN_CPP_EXTERN connection_options& sasl_config_path(const std::string&); + + /// **Unsettled API** - Set reconnect and failover options. + PN_CPP_EXTERN connection_options& reconnect(const reconnect_options &); + + /// Update option values from values set in other. + PN_CPP_EXTERN connection_options& update(const connection_options& other); + + private: + void apply_unbound(connection&) const; + void apply_unbound_client(pn_transport_t*) const; + void apply_unbound_server(pn_transport_t*) const; + messaging_handler* handler() const; + + class impl; + internal::pn_unique_ptr<impl> impl_; + + /// @cond INTERNAL + friend class container; + friend class io::connection_driver; + friend class connection; + /// @endcond +}; + +} // proton + +#endif // PROTON_CONNECTION_OPTIONS_H http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/container.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/container.hpp b/cpp/include/proton/container.hpp new file mode 100644 index 0000000..c6a876c --- /dev/null +++ b/cpp/include/proton/container.hpp @@ -0,0 +1,332 @@ +#ifndef PROTON_CONTAINER_HPP +#define PROTON_CONTAINER_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 "./fwd.hpp" +#include "./returned.hpp" +#include "./types_fwd.hpp" + +#include "./internal/config.hpp" +#include "./internal/export.hpp" +#include "./internal/pn_unique_ptr.hpp" + +#include <string> + +/// @file +/// @copybrief proton::container + +namespace proton { + +/// A top-level container of connections, sessions, and links. +/// +/// A container gives a unique identity to each communicating peer. It +/// is often a process-level object. +/// +/// It also serves as an entry point to the API, allowing connections, +/// senders, and receivers to be established. It can be supplied with +/// an event handler in order to intercept important messaging events, +/// such as newly received messages or newly issued credit for sending +/// messages. +class PN_CPP_CLASS_EXTERN container { + public: + /// Create a container with a global handler for messaging events. + /// + /// **Thread safety** - in a multi-threaded container this handler will be + /// called concurrently. You can use locks to make that safe, or use a + /// separate handler for each connection. See @ref mt_page. + /// + /// @param handler global handler, called for events on all connections + /// managed by the container. + /// + /// @param id sets the container's unique identity. + PN_CPP_EXTERN container(messaging_handler& handler, const std::string& id); + + /// Create a container with a global handler for messaging events. + /// + /// **Thread safety** - in a multi-threaded container this handler will be + /// called concurrently. You can use locks to make that safe, or use a + /// separate handler for each connection. See @ref mt_page. + /// + /// @param handler global handler, called for events on all connections + /// managed by the container. + PN_CPP_EXTERN container(messaging_handler& handler); + + /// Create a container. + /// @param id sets the container's unique identity. + PN_CPP_EXTERN container(const std::string& id); + + /// Create a container. + /// + /// This will create a default random identity + PN_CPP_EXTERN container(); + + /// Destroy a container. + /// + /// A container must not be destroyed while a call to run() is in progress, + /// in particular it must not be destroyed from a @ref messaging_handler + /// callback. + /// + /// **Thread safety** - in a multi-threaded application, run() must return + /// in all threads that call it before destroying the container. + /// + PN_CPP_EXTERN ~container(); + + /// Connect to `conn_url` and send an open request to the remote + /// peer. + /// + /// Options are applied to the connection as follows. + /// + /// 1. client_connection_options() + /// 2. Options passed to connect() + /// + /// Values in later options override earlier ones. The handler in + /// the composed options is used to call + /// `messaging_handler::on_connection_open()` when the open + /// response is received from the remote peer. + /// + /// @copydetails returned + PN_CPP_EXTERN returned<connection> connect(const std::string& conn_url, + const connection_options& conn_opts); + + /// @copybrief connect() + /// + /// @copydetails returned + PN_CPP_EXTERN returned<connection> connect(const std::string& conn_url); + + /// Listen for new connections on `listen_url`. + /// + /// If the listener opens successfully, listen_handler::on_open() is called. + /// If it fails to open, listen_handler::on_error() then listen_handler::close() + /// are called. + /// + /// listen_handler::on_accept() is called for each incoming connection to determine + /// the @ref connection_options to use, including the @ref messaging_handler. + /// + /// **Thread safety** - Calls to `listen_handler` methods are serialized for + /// this listener, but handlers attached to separate listeners may be called + /// concurrently. + PN_CPP_EXTERN listener listen(const std::string& listen_url, + listen_handler& handler); + + /// @copybrief listen + /// + /// Use a fixed set of options for all accepted connections. See + /// listen(const std::string&, listen_handler&). + /// + /// **Thread safety** - for multi-threaded applications we recommend using a + /// @ref listen_handler to create a new @ref messaging_handler for each connection. + /// See listen(const std::string&, listen_handler&) and @ref mt_page + PN_CPP_EXTERN listener listen(const std::string& listen_url, + const connection_options& conn_opts); + + /// @copybrief listen + /// + /// New connections will use the handler from + /// `server_connection_options()`. See listen(const std::string&, const + /// connection_options&); + PN_CPP_EXTERN listener listen(const std::string& listen_url); + + /// Run the container in the current thread. + /// + /// The call returns when the container stops. See `auto_stop()` + /// and `stop()`. + /// + /// **C++ versions** - With C++11 or later, you can call `run()` + /// in multiple threads to create a thread pool. See also + /// `run(int count)`. + PN_CPP_EXTERN void run(); + +#if PN_CPP_SUPPORTS_THREADS + /// Run the container with a pool of `count` threads, including the current thread. + /// + /// **C++ versions** - Available with C++11 or later. + /// + /// The call returns when the container stops. See `auto_stop()` + /// and `stop()`. + PN_CPP_EXTERN void run(int count); +#endif + + /// Enable or disable automatic container stop. It is enabled by + /// default. + /// + /// If true, the container stops when all active connections and + /// listeners are closed. If false, the container keeps running + /// until `stop()` is called. + PN_CPP_EXTERN void auto_stop(bool enabled); + + /// Stop the container with error condition `err`. + /// + /// @copydetails stop() + PN_CPP_EXTERN void stop(const error_condition& err); + + /// Stop the container with an empty error condition. + /// + /// This function initiates shutdown and immediately returns. The + /// shutdown process has the following steps. + /// + /// - Abort all open connections and listeners. + /// - Process final handler events and queued work. + /// - If `!err.empty()`, fire `messaging_handler::on_transport_error`. + /// + /// When the process is complete, `run()` returns in all threads. + /// + /// **Thread safety** - It is safe to call this method in any thread. + PN_CPP_EXTERN void stop(); + + /// Open a connection and sender for `addr_url`. + /// + /// @copydetails returned + PN_CPP_EXTERN returned<sender> open_sender(const std::string& addr_url); + + /// Open a connection and sender for `addr_url`. + /// + /// Supplied sender options will override the container's + /// template options. + /// + /// @copydetails returned + PN_CPP_EXTERN returned<sender> open_sender(const std::string& addr_url, + const proton::sender_options& snd_opts); + + /// Open a connection and sender for `addr_url`. + /// + /// Supplied connection options will override the + /// container's template options. + /// + /// @copydetails returned + PN_CPP_EXTERN returned<sender> open_sender(const std::string& addr_url, + const connection_options& conn_opts); + + /// Open a connection and sender for `addr_url`. + /// + /// Supplied sender or connection options will override the + /// container's template options. + /// + /// @copydetails returned + PN_CPP_EXTERN returned<sender> open_sender(const std::string& addr_url, + const proton::sender_options& snd_opts, + const connection_options& conn_opts); + + /// Open a connection and receiver for `addr_url`. + /// + /// @copydetails returned + PN_CPP_EXTERN returned<receiver> open_receiver(const std::string& addr_url); + + + /// Open a connection and receiver for `addr_url`. + /// + /// Supplied receiver options will override the container's + /// template options. + /// + /// @copydetails returned + PN_CPP_EXTERN returned<receiver> open_receiver(const std::string& addr_url, + const proton::receiver_options& rcv_opts); + + /// Open a connection and receiver for `addr_url`. + /// + /// Supplied receiver or connection options will override the + /// container's template options. + /// + /// @copydetails returned + PN_CPP_EXTERN returned<receiver> open_receiver(const std::string& addr_url, + const connection_options& conn_opts); + + /// Open a connection and receiver for `addr_url`. + /// + /// Supplied receiver or connection options will override the + /// container's template options. + /// + /// @copydetails returned + PN_CPP_EXTERN returned<receiver> open_receiver(const std::string& addr_url, + const proton::receiver_options& rcv_opts, + const connection_options& conn_opts); + + /// A unique identifier for the container. + PN_CPP_EXTERN std::string id() const; + + /// Connection options applied to outgoing connections. These are + /// applied first and then overridden by any options provided in + /// `connect()` or `messaging_handler::on_connection_open()`. + PN_CPP_EXTERN void client_connection_options(const connection_options& conn_opts); + + /// @copydoc client_connection_options + PN_CPP_EXTERN connection_options client_connection_options() const; + + /// Connection options applied to incoming connections. These are + /// applied first and then overridden by any options provided in + /// `listen()`, `listen_handler::on_accept()`, or + /// `messaging_handler::on_connection_open()`. + PN_CPP_EXTERN void server_connection_options(const connection_options& conn_opts); + + /// @copydoc server_connection_options + PN_CPP_EXTERN connection_options server_connection_options() const; + + /// Sender options applied to senders created by this + /// container. They are applied before + /// `messaging_handler::on_sender_open()` and can be overridden. + PN_CPP_EXTERN void sender_options(const class sender_options& snd_opts); + + /// @copydoc sender_options + PN_CPP_EXTERN class sender_options sender_options() const; + + /// Receiver options applied to receivers created by this + /// container. They are applied before + /// `messaging_handler::on_receiver_open()` and can be overridden. + PN_CPP_EXTERN void receiver_options(const class receiver_options& rcv_opts); + + /// @copydoc receiver_options + PN_CPP_EXTERN class receiver_options receiver_options() const; + + /// Schedule `fn` for execution after a duration. The piece of + /// work can be created from a function object. + /// + /// **C++ versions** - With C++11 and later, use a + /// `std::function<void()>` type for the `fn` parameter. + PN_CPP_EXTERN void schedule(duration dur, work fn); + + /// **Deprecated** - Use `container::schedule(duration, work)`. + PN_CPP_EXTERN PN_CPP_DEPRECATED("Use 'container::schedule(duration, work)'") void schedule(duration dur, void_function0& fn); + + /// @cond INTERNAL + // This is a hack to ensure that the C++03 version is declared + // only during the compilation of the library +#if PN_CPP_HAS_LAMBDAS && PN_CPP_HAS_VARIADIC_TEMPLATES && defined(qpid_proton_cpp_EXPORTS) + PN_CPP_EXTERN void schedule(duration dur, internal::v03::work fn); +#endif + /// @endcond + + private: + class impl; + internal::pn_unique_ptr<impl> impl_; + + /// @cond INTERNAL + friend class connection_options; + friend class session_options; + friend class receiver_options; + friend class sender_options; + friend class work_queue; + /// @endcond +}; + +} // proton + +#endif // PROTON_CONTAINER_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/decimal.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/decimal.hpp b/cpp/include/proton/decimal.hpp new file mode 100644 index 0000000..86c9013 --- /dev/null +++ b/cpp/include/proton/decimal.hpp @@ -0,0 +1,65 @@ +#ifndef PROTON_DECIMAL_HPP +#define PROTON_DECIMAL_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 "./byte_array.hpp" +#include "./internal/export.hpp" +#include "./internal/comparable.hpp" + +#include <iosfwd> + +/// @file +/// +/// AMQP decimal types. +/// +/// AMQP uses the standard IEEE 754-2008 encoding for decimal types. +/// +/// This library does not provide support for decimal arithmetic, but +/// it does provide access to the byte representation of decimal +/// values. You can pass these values uninterpreted via AMQP, or you +/// can use a library that supports IEEE 754-2008 and make a byte-wise +/// copy between the real decimal values and `proton::decimal` values. + +namespace proton { + +/// A 32-bit decimal floating-point value. +class decimal32 : public byte_array<4> {}; + +/// A 64-bit decimal floating-point value. +class decimal64 : public byte_array<8> {}; + +/// A 128-bit decimal floating-point value. +class decimal128 : public byte_array<16> {}; + +/// Print a 32-bit decimal value. +PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const decimal32&); + +/// Print a 64-bit decimal value. +PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const decimal64&); + +/// Print a 128-bit decimal value. +PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const decimal128&); + +} // proton + +#endif // PROTON_DECIMAL_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/default_container.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/default_container.hpp b/cpp/include/proton/default_container.hpp new file mode 100644 index 0000000..ba49be9 --- /dev/null +++ b/cpp/include/proton/default_container.hpp @@ -0,0 +1,37 @@ +#ifndef PROTON_DEFAULT_CONTAINER_HPP +#define PROTON_DEFAULT_CONTAINER_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 "./internal/export.hpp" + +/// @file +/// **Deprecated** - Use the API in `container.hpp`. + +namespace proton { + +/// **Deprecated** - Use `proton::container`. +typedef class container PN_CPP_DEPRECATED("Use 'proton::container'") default_container; + +} // proton + +#endif // PROTON_DEFAULT_CONTAINER_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/delivery.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/delivery.hpp b/cpp/include/proton/delivery.hpp new file mode 100644 index 0000000..61a2fbe --- /dev/null +++ b/cpp/include/proton/delivery.hpp @@ -0,0 +1,72 @@ +#ifndef PROTON_DELIVERY_HPP +#define PROTON_DELIVERY_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 "./fwd.hpp" +#include "./internal/export.hpp" +#include "./internal/object.hpp" +#include "./transfer.hpp" + +/// @file +/// @copybrief proton::delivery + +namespace proton { + +/// A received message. +/// +/// A delivery attempt can fail. As a result, a particular message may +/// correspond to multiple deliveries. +class delivery : public transfer { + /// @cond INTERNAL + delivery(pn_delivery_t* d); + /// @endcond + + public: + delivery() {} + + /// Return the receiver for this delivery. + PN_CPP_EXTERN class receiver receiver() const; + + // XXX ATM the following don't reflect the differing behaviors we + // get from the different delivery modes. - Deferred + + /// Settle with ACCEPTED state. + PN_CPP_EXTERN void accept(); + + /// Settle with REJECTED state. + PN_CPP_EXTERN void reject(); + + /// Settle with RELEASED state. + PN_CPP_EXTERN void release(); + + /// Settle with MODIFIED state. + PN_CPP_EXTERN void modify(); + + /// @cond INTERNAL + friend class internal::factory<delivery>; + /// @endcond +}; + +} // proton + +#endif // PROTON_DELIVERY_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/delivery_mode.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/delivery_mode.hpp b/cpp/include/proton/delivery_mode.hpp new file mode 100644 index 0000000..744bd2c --- /dev/null +++ b/cpp/include/proton/delivery_mode.hpp @@ -0,0 +1,63 @@ +#ifndef PROTON_DELIVERY_MODE_H +#define PROTON_DELIVERY_MODE_H + +/* + * + * 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. + * + */ + +/// @file +/// @copybrief proton::delivery_mode + +namespace proton { + +/// The message delivery policy to establish when opening a link. +/// This structure imitates the newer C++11 "enum class" so that +/// The enumeration constants are in the delivery_mode namespace. +struct delivery_mode { + /// Delivery modes + enum modes { + /// No set policy. The application must settle messages + /// itself according to its own policy. + NONE = 0, + /// Outgoing messages are settled immediately by the link. + /// There are no duplicates. + AT_MOST_ONCE, + /// The receiver settles the delivery first with an + /// accept/reject/release disposition. The sender waits to + /// settle until after the disposition notification is + /// received. + AT_LEAST_ONCE + }; + + /// @cond INTERNAL + + delivery_mode() : modes_(NONE) {} + delivery_mode(modes m) : modes_(m) {} + operator modes() { return modes_; } + + /// @endcond + + private: + modes modes_; +}; + +} // proton + +#endif // PROTON_DELIVERY_MODE_H http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/duration.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/duration.hpp b/cpp/include/proton/duration.hpp new file mode 100644 index 0000000..f073de5 --- /dev/null +++ b/cpp/include/proton/duration.hpp @@ -0,0 +1,80 @@ +#ifndef PROTON_DURATION_HPP +#define PROTON_DURATION_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 "./internal/export.hpp" +#include "./internal/comparable.hpp" +#include "./types_fwd.hpp" + +#include <proton/type_compat.h> + +#include <iosfwd> + +/// @file +/// @copybrief proton::duration + +namespace proton { + +/// A span of time in milliseconds. +class duration : private internal::comparable<duration> { + public: + /// A numeric type holding a value in milliseconds. + typedef int64_t numeric_type; + + /// Construct from a value in milliseconds. + explicit duration(numeric_type ms = 0) : ms_(ms) {} + + /// Assign a value in milliseconds. + duration& operator=(numeric_type ms) { ms_ = ms; return *this; } + + /// Get the value in milliseconds. + numeric_type milliseconds() const { return ms_; } + + PN_CPP_EXTERN static const duration FOREVER; ///< Wait forever + PN_CPP_EXTERN static const duration IMMEDIATE; ///< Don't wait at all + PN_CPP_EXTERN static const duration SECOND; ///< One second + PN_CPP_EXTERN static const duration MILLISECOND; ///< One millisecond + PN_CPP_EXTERN static const duration MINUTE; ///< One minute + + private: + numeric_type ms_; +}; + +/// Print a duration. +PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, duration); + +/// @name Comparison and arithmetic operators +/// @{ +inline bool operator<(duration x, duration y) { return x.milliseconds() < y.milliseconds(); } +inline bool operator==(duration x, duration y) { return x.milliseconds() == y.milliseconds(); } + +inline duration operator+(duration x, duration y) { return duration(x.milliseconds() + y.milliseconds()); } +inline duration operator-(duration x, duration y) { return duration(x.milliseconds() - y.milliseconds()); } +inline duration operator*(duration d, uint64_t n) { return duration(d.milliseconds()*n); } +inline duration operator*(uint64_t n, duration d) { return d * n; } +inline duration operator/(duration d, uint64_t n) { return duration(d.milliseconds() / n); } +/// @} + +} // proton + +#endif // PROTON_DURATION_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/endpoint.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/endpoint.hpp b/cpp/include/proton/endpoint.hpp new file mode 100644 index 0000000..8fc3b27 --- /dev/null +++ b/cpp/include/proton/endpoint.hpp @@ -0,0 +1,113 @@ +#ifndef PROTON_ENDPOINT_HPP +#define PROTON_ENDPOINT_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 "./fwd.hpp" +#include "./error_condition.hpp" +#include "./internal/config.hpp" +#include "./internal/export.hpp" + +/// @file +/// @copybrief proton::endpoint + +namespace proton { + +/// The base class for session, connection, and link. +class +PN_CPP_CLASS_EXTERN endpoint { + public: + PN_CPP_EXTERN virtual ~endpoint(); + + // XXX Add the container accessor here. + + /// True if the local end is uninitialized. + virtual bool uninitialized() const = 0; + + /// True if the local end is active. + virtual bool active() const = 0; + + /// True if the local and remote ends are closed. + virtual bool closed() const = 0; + + /// Get the error condition of the remote endpoint. + virtual class error_condition error() const = 0; + + // XXX Add virtual open() and open(endpoint_options) + + /// Close the endpoint. + /// + /// @see endpoint_lifecycle + virtual void close() = 0; + + /// Close the endpoint with an error condition. + /// + /// @see endpoint_lifecycle + virtual void close(const error_condition&) = 0; + +#if PN_CPP_HAS_DEFAULTED_FUNCTIONS && PN_CPP_HAS_DEFAULTED_MOVE_INITIALIZERS + // Make everything explicit for C++11 compilers + + /// @cond INTERNAL + endpoint() = default; + endpoint& operator=(const endpoint&) = default; + endpoint(const endpoint&) = default; + endpoint& operator=(endpoint&&) = default; + endpoint(endpoint&&) = default; + /// @endcond +#endif +}; + +namespace internal { + +template <class T, class D> class iter_base { + public: + typedef T value_type; + + T operator*() const { return obj_; } + T* operator->() const { return const_cast<T*>(&obj_); } + D operator++(int) { D x(*this); ++(*this); return x; } + bool operator==(const iter_base<T, D>& x) const { return obj_ == x.obj_; } + bool operator!=(const iter_base<T, D>& x) const { return obj_ != x.obj_; } + + protected: + explicit iter_base(T p = 0) : obj_(p) {} + T obj_; +}; + +template<class I> class iter_range { + public: + typedef I iterator; + + explicit iter_range(I begin = I(), I end = I()) : begin_(begin), end_(end) {} + I begin() const { return begin_; } + I end() const { return end_; } + bool empty() const { return begin_ == end_; } + + private: + I begin_, end_; +}; + +} // internal +} // proton + +#endif // PROTON_ENDPOINT_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/error.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/error.hpp b/cpp/include/proton/error.hpp new file mode 100644 index 0000000..53643ba --- /dev/null +++ b/cpp/include/proton/error.hpp @@ -0,0 +1,62 @@ +#ifndef PROTON_ERROR_HPP +#define PROTON_ERROR_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 "./internal/config.hpp" +#include "./internal/export.hpp" + +#include <stdexcept> +#include <string> + +/// @file +/// @copybrief proton::error + +namespace proton { + +/// The base Proton error. +/// +/// All exceptions thrown from functions in the proton namespace are +/// subclasses of proton::error. +struct +PN_CPP_CLASS_EXTERN error : public std::runtime_error { + /// Construct the error with a message. + PN_CPP_EXTERN explicit error(const std::string&); +}; + +/// An operation timed out. +struct +PN_CPP_CLASS_EXTERN timeout_error : public error { + /// Construct the error with a message. + PN_CPP_EXTERN explicit timeout_error(const std::string&); +}; + +/// An error converting between AMQP and C++ data. +struct +PN_CPP_CLASS_EXTERN conversion_error : public error { + /// Construct the error with a message. + PN_CPP_EXTERN explicit conversion_error(const std::string&); +}; + +} // proton + +#endif // PROTON_ERROR_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/error_condition.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/error_condition.hpp b/cpp/include/proton/error_condition.hpp new file mode 100644 index 0000000..cbd6e09 --- /dev/null +++ b/cpp/include/proton/error_condition.hpp @@ -0,0 +1,112 @@ +#ifndef PROTON_ERROR_CONDITION_H +#define PROTON_ERROR_CONDITION_H + +/* + * + * 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 "./internal/export.hpp" +#include "./internal/config.hpp" +#include "./value.hpp" + +#include <string> +#include <iosfwd> + +/// @file +/// @copybrief proton::error_condition + +struct pn_condition_t; + +namespace proton { + +/// Describes an endpoint error state. +class error_condition { + /// @cond INTERNAL + error_condition(pn_condition_t* c); + /// @endcond + + public: + /// Create an empty error condition. + error_condition() {} + + /// Create an error condition with only a description. A default + /// name will be used ("proton:io:error"). + PN_CPP_EXTERN error_condition(std::string description); + + /// Create an error condition with a name and description. + PN_CPP_EXTERN error_condition(std::string name, std::string description); + + /// **Unsettled API** - Create an error condition with name, + /// description, and informational properties. + PN_CPP_EXTERN error_condition(std::string name, std::string description, proton::value properties); + +#if PN_CPP_HAS_DEFAULTED_FUNCTIONS && PN_CPP_HAS_DEFAULTED_MOVE_INITIALIZERS + /// @cond INTERNAL + error_condition(const error_condition&) = default; + error_condition& operator=(const error_condition&) = default; + error_condition(error_condition&&) = default; + error_condition& operator=(error_condition&&) = default; + /// @endcond +#endif + +#if PN_CPP_HAS_EXPLICIT_CONVERSIONS + /// If you are using a C++11 compiler, you may use an + /// error_condition in boolean contexts. The expression will be + /// true if the error_condition is set. + PN_CPP_EXTERN explicit operator bool() const; +#endif + + /// No condition set. + PN_CPP_EXTERN bool operator!() const; + + /// No condition has been set. + PN_CPP_EXTERN bool empty() const; + + /// Condition name. + PN_CPP_EXTERN std::string name() const; + + /// Descriptive string for condition. + PN_CPP_EXTERN std::string description() const; + + /// Extra information for condition. + PN_CPP_EXTERN value properties() const; + + /// Simple printable string for condition. + PN_CPP_EXTERN std::string what() const; + + private: + std::string name_; + std::string description_; + proton::value properties_; + + /// @cond INTERNAL + friend class internal::factory<error_condition>; + /// @endcond +}; + +/// @cond INTERNAL +// XXX Document these +PN_CPP_EXTERN bool operator==(const error_condition& x, const error_condition& y); +PN_CPP_EXTERN std::ostream& operator<<(std::ostream& o, const error_condition& err); +/// @endcond + +} // proton + +#endif // PROTON_ERROR_CONDITION_H http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/function.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/function.hpp b/cpp/include/proton/function.hpp new file mode 100644 index 0000000..2089717 --- /dev/null +++ b/cpp/include/proton/function.hpp @@ -0,0 +1,53 @@ +#ifndef PROTON_FUNCTION_HPP +#define PROTON_FUNCTION_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. + */ + +/// @file +/// **Deprecated** - Use the API in `work_queue.hpp`. + +/// @cond INTERNAL + +namespace proton { + +/// **Deprecated** - Use `proton::work`. +/// +/// A C++03-compatible void no-argument callback function object. +/// +/// Used by `container::schedule()` and `work_queue::add()`. In C++11 +/// you can use `std::bind`, `std::function`, or a void-no-argument +/// lambda instead. +/// +/// `void_function0` is passed by reference, so instances of +/// subclasses do not have to be heap allocated. Once passed, the +/// instance must not be deleted until its `operator()` is called or +/// the container has stopped. +class void_function0 { + public: + virtual ~void_function0() {} + /// Override the call operator with your code. + virtual void operator()() = 0; +}; + +} // proton + +/// @endcond + +#endif // PROTON_FUNCTION_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/fwd.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/fwd.hpp b/cpp/include/proton/fwd.hpp new file mode 100644 index 0000000..5ae1d8a --- /dev/null +++ b/cpp/include/proton/fwd.hpp @@ -0,0 +1,82 @@ +#ifndef PROTON_FWD_HPP +#define PROTON_FWD_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. + * + */ + +/// @file +/// Forward declarations. + +#include "./internal/config.hpp" + +namespace proton { + +class annotation_key; +class connection; +class connection_options; +class container; +class delivery; +class duration; +class error_condition; +class event; +class message; +class message_id; +class messaging_handler; +class listen_handler; +class listener; +class receiver; +class receiver_iterator; +class receiver_options; +class reconnect_options; +class sasl; +class sender; +class sender_iterator; +class sender_options; +class session; +class session_options; +class source_options; +class ssl; +class target_options; +class tracker; +class transport; +class url; +class void_function0; +class work_queue; + +namespace internal { namespace v03 { class work; } } + +#if PN_CPP_HAS_LAMBDAS && PN_CPP_HAS_VARIADIC_TEMPLATES +namespace internal { namespace v11 { class work; } } +using internal::v11::work; +#else +using internal::v03::work; +#endif + +namespace io { + +class connection_driver; + +} + +template <class T> class returned; +} + +#endif // PROTON_FWD_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/internal/comparable.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/internal/comparable.hpp b/cpp/include/proton/internal/comparable.hpp new file mode 100644 index 0000000..b93ec4b --- /dev/null +++ b/cpp/include/proton/internal/comparable.hpp @@ -0,0 +1,40 @@ +#ifndef PROTON_INTERNAL_COMPARABLE_HPP +#define PROTON_INTERNAL_COMPARABLE_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. + * + */ + +namespace proton { +namespace internal { + +/// Base class for comparable types with operator< and +/// operator==. Provides remaining operators. +template <class T> class comparable { + friend bool operator>(const T &a, const T &b) { return b < a; } + friend bool operator<=(const T &a, const T &b) { return !(a > b); } + friend bool operator>=(const T &a, const T &b) { return !(a < b); } + friend bool operator!=(const T &a, const T &b) { return !(a == b); } +}; + +} // internal +} // proton + +#endif // PROTON_INTERNAL_COMPARABLE_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/internal/config.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/internal/config.hpp b/cpp/include/proton/internal/config.hpp new file mode 100644 index 0000000..321aebf --- /dev/null +++ b/cpp/include/proton/internal/config.hpp @@ -0,0 +1,137 @@ +#ifndef PROTON_INTERNAL_CONFIG_HPP +#define PROTON_INTERNAL_CONFIG_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. + * + */ + +/// @cond INTERNAL + +/// @file +/// +/// Configuration macros. They can be set via -D compiler options or +/// in code. +/// +/// On a C++11 compliant compiler, all C++11 features are enabled by +/// default. Otherwise they can be enabled or disabled separately +/// with -D on the compile line. + +// Read library compilation presets - +// This sets the options the library itself was compiled with +// and sets up the compilation options is we are compiling the library itself +#include "config_presets.hpp" + +/// Whether the library supports threads depends on the configuration of the library compilation only +#define PN_CPP_SUPPORTS_THREADS PN_CPP_LIB_HAS_CPP11 || (PN_CPP_LIB_HAS_STD_THREAD && PN_CPP_LIB_HAS_STD_MUTEX) +/// @endcond + +/// The Apple clang compiler doesn't really support PN_CPP_HAS_THREAD_LOCAL +/// before Xcode 8 even though it claims to be C++11 compatible +#if defined(__clang__) && defined(__apple_build_version__) && ((__clang_major__ * 100) + __clang_minor__) >= 301 +#if __has_feature(cxx_thread_local) +#define PN_CPP_HAS_THREAD_LOCAL 1 +#else +#define PN_CPP_HAS_THREAD_LOCAL 0 +#endif +#endif + +#ifndef PN_CPP_HAS_CPP11 +#if defined(__cplusplus) && __cplusplus >= 201103 +#define PN_CPP_HAS_CPP11 1 +#else +#define PN_CPP_HAS_CPP11 0 +#endif +#endif + +#ifndef PN_CPP_HAS_LONG_LONG_TYPE +#define PN_CPP_HAS_LONG_LONG_TYPE PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_NULLPTR +#define PN_CPP_HAS_NULLPTR PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_RVALUE_REFERENCES +#define PN_CPP_HAS_RVALUE_REFERENCES PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_OVERRIDE +#define PN_CPP_HAS_OVERRIDE PN_CPP_HAS_CPP11 +#endif + +#if PN_CPP_HAS_OVERRIDE +#define PN_CPP_OVERRIDE override +#else +#define PN_CPP_OVERRIDE +#endif + +#ifndef PN_CPP_HAS_EXPLICIT_CONVERSIONS +#define PN_CPP_HAS_EXPLICIT_CONVERSIONS PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_DEFAULTED_FUNCTIONS +#define PN_CPP_HAS_DEFAULTED_FUNCTIONS PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_DEFAULTED_MOVE_INITIALIZERS +#define PN_CPP_HAS_DEFAULTED_MOVE_INITIALIZERS PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_DELETED_FUNCTIONS +#define PN_CPP_HAS_DELETED_FUNCTIONS PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_THREAD_LOCAL +#define PN_CPP_HAS_THREAD_LOCAL PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_VARIADIC_TEMPLATES +#define PN_CPP_HAS_VARIADIC_TEMPLATES PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_LAMBDAS +#define PN_CPP_HAS_LAMBDAS PN_CPP_HAS_CPP11 +#endif + +// Library features + +#ifndef PN_CPP_HAS_HEADER_RANDOM +#define PN_CPP_HAS_HEADER_RANDOM PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_STD_UNIQUE_PTR +#define PN_CPP_HAS_STD_UNIQUE_PTR PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_STD_MUTEX +#define PN_CPP_HAS_STD_MUTEX PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_STD_ATOMIC +#define PN_CPP_HAS_STD_ATOMIC PN_CPP_HAS_CPP11 +#endif + +#ifndef PN_CPP_HAS_STD_THREAD +#define PN_CPP_HAS_STD_THREAD PN_CPP_HAS_CPP11 +#endif + +#endif // PROTON_INTERNAL_CONFIG_HPP + +/// @endcond http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/internal/data.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/internal/data.hpp b/cpp/include/proton/internal/data.hpp new file mode 100644 index 0000000..fdbd368 --- /dev/null +++ b/cpp/include/proton/internal/data.hpp @@ -0,0 +1,105 @@ +#ifndef PROTON_INTERNAL_DATA_HPP +#define PROTON_INTERNAL_DATA_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 "../internal/object.hpp" +#include "../types_fwd.hpp" + +struct pn_data_t; + +namespace proton { + +class value; + +namespace internal { + +/// @cond INTERNAL +/// A wrapper for a proton data object. +class data : public object<pn_data_t> { + /// Wrap an existing Proton-C data object. + data(pn_data_t* d) : internal::object<pn_data_t>(d) {} + + public: + /// Create an empty data object. + data() : internal::object<pn_data_t>(0) {} + + /// Create a new data object. + PN_CPP_EXTERN static data create(); + + /// Copy the contents of another data object. + PN_CPP_EXTERN void copy(const data&); + + /// Clear the data. + PN_CPP_EXTERN void clear(); + + /// Rewind current position to the start. + PN_CPP_EXTERN void rewind(); + + /// True if there are no values. + PN_CPP_EXTERN bool empty() const; + + /// Append the contents of another data object. + PN_CPP_EXTERN int append(data src); + + /// Append up to limit items from data object. + PN_CPP_EXTERN int appendn(data src, int limit); + + PN_CPP_EXTERN bool next(); + PN_CPP_EXTERN const void* point() const; + PN_CPP_EXTERN void restore(const void* h); + + protected: + void narrow(); + void widen(); + + friend class internal::factory<data>; + friend struct state_guard; + friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const data&); +}; +/// @endcond + +/// **Unsettled API** - Save and restore codec state. +/// +/// A state guard saves the state and restores it in the destructor +/// unless `cancel()` is called. +struct state_guard { + /// @cond INTERNAL + data& data_; + const void* point_; + bool cancel_; + /// @endcond + + /// @cond INTERNAL + state_guard(data& d) : data_(d), point_(data_.point()), cancel_(false) {} + /// @endcond + + ~state_guard() { if (!cancel_) data_.restore(point_); } + + /// Discard the saved state. + void cancel() { cancel_ = true; } +}; + +} // internal +} // proton + +#endif // PROTON_INTERNAL_DATA_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/internal/export.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/internal/export.hpp b/cpp/include/proton/internal/export.hpp new file mode 100644 index 0000000..d7a365d --- /dev/null +++ b/cpp/include/proton/internal/export.hpp @@ -0,0 +1,76 @@ +#ifndef PROTON_INTERNAL_EXPORT_HPP +#define PROTON_INTERNAL_EXPORT_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. + * + */ + +/// @cond INTERNAL + +/// import/export macros +#if defined(WIN32) && !defined(PN_CPP_DECLARE_STATIC) + // + // Import and Export definitions for Windows: + // +# define PN_CPP_EXPORT __declspec(dllexport) +# define PN_CPP_IMPORT __declspec(dllimport) +# define PN_CPP_CLASS_EXPORT +# define PN_CPP_CLASS_IMPORT +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# define PN_CPP_EXPORT __global +# define PN_CPP_IMPORT +# define PN_CPP_CLASS_EXPORT __global +# define PN_CPP_CLASS_IMPORT +#else + // + // Non-Windows (Linux, etc.) definitions: + // +# define PN_CPP_EXPORT __attribute__((visibility("default"))) +# define PN_CPP_IMPORT +# define PN_CPP_CLASS_EXPORT __attribute__((visibility("default"))) +# define PN_CPP_CLASS_IMPORT +#endif + +// For qpid-proton-cpp library symbols +#ifdef qpid_proton_cpp_EXPORTS +# define PN_CPP_EXTERN PN_CPP_EXPORT +# define PN_CPP_CLASS_EXTERN PN_CPP_CLASS_EXPORT +#else +# define PN_CPP_EXTERN PN_CPP_IMPORT +# define PN_CPP_CLASS_EXTERN PN_CPP_CLASS_IMPORT +#endif + +#if defined(PN_CPP_USE_DEPRECATED_API) +# define PN_CPP_DEPRECATED(message) +#else +# if defined(PN_COMPILER_CXX_ATTRIBUTE_DEPRECATED) && PN_COMPILER_CXX_ATTRIBUTE_DEPRECATED +# define PN_CPP_DEPRECATED(message) [[deprecated(message)]] +# elif defined(WIN32) +# define PN_CPP_DEPRECATED(message) __declspec(deprecated(message)) +# elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40500 +# define PN_CPP_DEPRECATED(message) __attribute__((deprecated)) +# else +# define PN_CPP_DEPRECATED(message) __attribute__((deprecated(message))) +# endif +#endif + +/// @endcond + +#endif // PROTON_INTERNAL_EXPORT_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/internal/object.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/internal/object.hpp b/cpp/include/proton/internal/object.hpp new file mode 100644 index 0000000..7f116c9 --- /dev/null +++ b/cpp/include/proton/internal/object.hpp @@ -0,0 +1,114 @@ +#ifndef PROTON_INTERNAL_OBJECT_HPP +#define PROTON_INTERNAL_OBJECT_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 "./config.hpp" +#include "./export.hpp" +#include "./comparable.hpp" + +#include <memory> +#include <string> + +namespace proton { + +template <class T> class returned; + +namespace internal { + +class pn_ptr_base { + protected: + PN_CPP_EXTERN static void incref(void* p); + PN_CPP_EXTERN static void decref(void* p); + PN_CPP_EXTERN static std::string inspect(void* p); +}; + +template <class T> class pn_ptr : private pn_ptr_base, private comparable<pn_ptr<T> > { + public: + pn_ptr() : ptr_(0) {} + pn_ptr(T* p) : ptr_(p) { incref(ptr_); } + pn_ptr(const pn_ptr& o) : ptr_(o.ptr_) { incref(ptr_); } + +#if PN_CPP_HAS_RVALUE_REFERENCES + pn_ptr(pn_ptr&& o) : ptr_(0) { std::swap(ptr_, o.ptr_); } +#endif + + ~pn_ptr() { decref(ptr_); } + + pn_ptr& operator=(pn_ptr o) { std::swap(ptr_, o.ptr_); return *this; } + + T* get() const { return ptr_; } + T* release() { T *p = ptr_; ptr_ = 0; return p; } + + bool operator!() const { return !ptr_; } + +#if PN_CPP_HAS_EXPLICIT_CONVERSIONS + explicit operator bool() const { return !!ptr_; } +#endif + + std::string inspect() const { return pn_ptr_base::inspect(ptr_); } + + static pn_ptr take_ownership(T* p) { return pn_ptr<T>(p, true); } + + private: + T *ptr_; + + // Note that it is the presence of the bool in the constructor signature that matters + // to get the "transfer ownership" constructor: The value of the bool isn't checked. + pn_ptr(T* p, bool) : ptr_(p) {} + + friend bool operator==(const pn_ptr& a, const pn_ptr& b) { return a.ptr_ == b.ptr_; } + friend bool operator<(const pn_ptr& a, const pn_ptr& b) { return a.ptr_ < b.ptr_; } +}; + +template <class T> pn_ptr<T> take_ownership(T* p) { return pn_ptr<T>::take_ownership(p); } + +/// Base class for proton object types. +template <class T> class object : private comparable<object<T> > { + public: + bool operator!() const { return !object_; } +#if PN_CPP_HAS_EXPLICIT_CONVERSIONS + explicit operator bool() const { return object_.get(); } +#endif + + protected: + typedef T pn_type; + object(pn_ptr<T> o) : object_(o) {} + T* pn_object() const { return object_.get(); } + + private: + pn_ptr<T> object_; + + friend bool operator==(const object& a, const object& b) { return a.object_ == b.object_; } + friend bool operator<(const object& a, const object& b) { return a.object_ < b.object_; } + friend std::ostream& operator<<(std::ostream& o, const object& a) { o << a.object_.inspect(); return o; } + + template <class U> friend class proton::returned; +}; + +/// Factory class used internally to make wrappers and extract proton objects +template <class T> class factory; + +} // internal +} // proton + +#endif // PROTON_INTERNAL_OBJECT_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/internal/pn_unique_ptr.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/internal/pn_unique_ptr.hpp b/cpp/include/proton/internal/pn_unique_ptr.hpp new file mode 100644 index 0000000..e47fbaa --- /dev/null +++ b/cpp/include/proton/internal/pn_unique_ptr.hpp @@ -0,0 +1,76 @@ +#ifndef PROTON_INTERNAL_UNIQUE_PTR_HPP +#define PROTON_INTERNAL_UNIQUE_PTR_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 "./config.hpp" + +#include <memory> + +namespace proton { +namespace internal { + +template <class T> class pn_unique_ptr; +template <class T> void swap(pn_unique_ptr<T>& x, pn_unique_ptr<T>& y); + +/// A simple unique ownership pointer, used as a return value from +/// functions that transfer ownership to the caller. +/// +/// pn_unique_ptr return values should be converted immediately to +/// std::unique_ptr if that is available or std::auto_ptr (by calling +/// release()) for older C++. You should not use pn_unique_ptr in your +/// own code. It is a limited pointer class designed only to work +/// around differences between C++11 and C++03. +template <class T> class pn_unique_ptr { + public: + pn_unique_ptr(T* p=0) : ptr_(p) {} +#if PN_CPP_HAS_RVALUE_REFERENCES + pn_unique_ptr(pn_unique_ptr&& x) : ptr_(0) { std::swap(ptr_, x.ptr_); } +#else + pn_unique_ptr(const pn_unique_ptr& x) : ptr_() { std::swap(ptr_, const_cast<pn_unique_ptr&>(x).ptr_); } +#endif + ~pn_unique_ptr() { delete(ptr_); } + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } + void reset(T* p = 0) { pn_unique_ptr<T> tmp(p); std::swap(ptr_, tmp.ptr_); } + T* release() { T *p = ptr_; ptr_ = 0; return p; } +#if PN_CPP_HAS_EXPLICIT_CONVERSIONS + explicit operator bool() const { return get(); } +#endif + bool operator !() const { return !get(); } + void swap(pn_unique_ptr& x) { std::swap(ptr_, x.ptr_); } + +#if PN_CPP_HAS_STD_UNIQUE_PTR + operator std::unique_ptr<T>() { T *p = ptr_; ptr_ = 0; return std::unique_ptr<T>(p); } +#endif + + private: + T* ptr_; +}; + +template <class T> void swap(pn_unique_ptr<T>& x, pn_unique_ptr<T>& y) { x.swap(y); } + +} // internal +} // proton + +#endif // PROTON_INTERNAL_UNIQUE_PTR_HPP http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/cpp/include/proton/internal/type_traits.hpp ---------------------------------------------------------------------- diff --git a/cpp/include/proton/internal/type_traits.hpp b/cpp/include/proton/internal/type_traits.hpp new file mode 100644 index 0000000..3f2a257 --- /dev/null +++ b/cpp/include/proton/internal/type_traits.hpp @@ -0,0 +1,186 @@ +#ifndef PROTON_INTERNAL_TYPE_TRAITS_HPP +#define PROTON_INTERNAL_TYPE_TRAITS_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. + * + */ + +// Type traits for mapping between AMQP and C++ types. +// +// Also provides workarounds for missing type_traits classes on older +// C++ compilers. + +#include "./config.hpp" +#include "../types_fwd.hpp" +#include "../type_id.hpp" + +#include <proton/type_compat.h> + +#include <limits> + +namespace proton { +namespace internal { + +class decoder; +class encoder; + +template <bool, class T=void> struct enable_if {}; +template <class T> struct enable_if<true, T> { typedef T type; }; + +struct true_type { static const bool value = true; }; +struct false_type { static const bool value = false; }; + +template <class T> struct is_integral : public false_type {}; +template <class T> struct is_signed : public false_type {}; + +template <> struct is_integral<char> : public true_type {}; +template <> struct is_signed<char> { static const bool value = std::numeric_limits<char>::is_signed; }; + +template <> struct is_integral<unsigned char> : public true_type {}; +template <> struct is_integral<unsigned short> : public true_type {}; +template <> struct is_integral<unsigned int> : public true_type {}; +template <> struct is_integral<unsigned long> : public true_type {}; + +template <> struct is_integral<signed char> : public true_type {}; +template <> struct is_integral<signed short> : public true_type {}; +template <> struct is_integral<signed int> : public true_type {}; +template <> struct is_integral<signed long> : public true_type {}; + +template <> struct is_signed<unsigned short> : public false_type {}; +template <> struct is_signed<unsigned int> : public false_type {}; +template <> struct is_signed<unsigned long> : public false_type {}; + +template <> struct is_signed<signed char> : public true_type {}; +template <> struct is_signed<signed short> : public true_type {}; +template <> struct is_signed<signed int> : public true_type {}; +template <> struct is_signed<signed long> : public true_type {}; + +#if PN_CPP_HAS_LONG_LONG_TYPE +template <> struct is_integral<unsigned long long> : public true_type {}; +template <> struct is_integral<signed long long> : public true_type {}; +template <> struct is_signed<unsigned long long> : public false_type {}; +template <> struct is_signed<signed long long> : public true_type {}; +#endif + +template <class T, class U> struct is_same { static const bool value=false; }; +template <class T> struct is_same<T,T> { static const bool value=true; }; + +template< class T > struct remove_const { typedef T type; }; +template< class T > struct remove_const<const T> { typedef T type; }; + +template <type_id ID, class T> struct type_id_constant { + typedef T type; + static const type_id value = ID; +}; + +/// @name Metafunction returning AMQP type for scalar C++ types. +/// @{ +template <class T> struct type_id_of; +template<> struct type_id_of<bool> : public type_id_constant<BOOLEAN, bool> {}; +template<> struct type_id_of<uint8_t> : public type_id_constant<UBYTE, uint8_t> {}; +template<> struct type_id_of<int8_t> : public type_id_constant<BYTE, int8_t> {}; +template<> struct type_id_of<uint16_t> : public type_id_constant<USHORT, uint16_t> {}; +template<> struct type_id_of<int16_t> : public type_id_constant<SHORT, int16_t> {}; +template<> struct type_id_of<uint32_t> : public type_id_constant<UINT, uint32_t> {}; +template<> struct type_id_of<int32_t> : public type_id_constant<INT, int32_t> {}; +template<> struct type_id_of<uint64_t> : public type_id_constant<ULONG, uint64_t> {}; +template<> struct type_id_of<int64_t> : public type_id_constant<LONG, int64_t> {}; +template<> struct type_id_of<wchar_t> : public type_id_constant<CHAR, wchar_t> {}; +template<> struct type_id_of<float> : public type_id_constant<FLOAT, float> {}; +template<> struct type_id_of<double> : public type_id_constant<DOUBLE, double> {}; +template<> struct type_id_of<timestamp> : public type_id_constant<TIMESTAMP, timestamp> {}; +template<> struct type_id_of<decimal32> : public type_id_constant<DECIMAL32, decimal32> {}; +template<> struct type_id_of<decimal64> : public type_id_constant<DECIMAL64, decimal64> {}; +template<> struct type_id_of<decimal128> : public type_id_constant<DECIMAL128, decimal128> {}; +template<> struct type_id_of<uuid> : public type_id_constant<UUID, uuid> {}; +template<> struct type_id_of<std::string> : public type_id_constant<STRING, std::string> {}; +template<> struct type_id_of<symbol> : public type_id_constant<SYMBOL, symbol> {}; +template<> struct type_id_of<binary> : public type_id_constant<BINARY, binary> {}; +#if PN_CPP_HAS_NULLPTR +template<> struct type_id_of<decltype(nullptr)> : public type_id_constant<NULL_TYPE, null> {}; +#endif +/// @} + +/// Metafunction to test if a class has a type_id. +template <class T, class Enable=void> struct has_type_id : public false_type {}; +template <class T> struct has_type_id<T, typename type_id_of<T>::type> : public true_type {}; + +// The known/unknown integer type magic is required because the C++ standard is +// vague a about the equivalence of integral types for overloading. E.g. char is +// sometimes equivalent to signed char, sometimes unsigned char, sometimes +// neither. int8_t or uint8_t may or may not be equivalent to a char type. +// int64_t may or may not be equivalent to long long etc. C++ compilers are also +// allowed to add their own non-standard integer types like __int64, which may +// or may not be equivalent to any of the standard integer types. +// +// The solution is to use a fixed, standard set of integer types that are +// guaranteed to be distinct for overloading (see type_id_of) and to use template +// specialization to convert other integer types to a known integer type with the +// same sizeof and is_signed. + +// Map arbitrary integral types to known integral types. +template<size_t SIZE, bool IS_SIGNED> struct integer_type; +template<> struct integer_type<1, true> { typedef int8_t type; }; +template<> struct integer_type<2, true> { typedef int16_t type; }; +template<> struct integer_type<4, true> { typedef int32_t type; }; +template<> struct integer_type<8, true> { typedef int64_t type; }; +template<> struct integer_type<1, false> { typedef uint8_t type; }; +template<> struct integer_type<2, false> { typedef uint16_t type; }; +template<> struct integer_type<4, false> { typedef uint32_t type; }; +template<> struct integer_type<8, false> { typedef uint64_t type; }; + +// True if T is an integer type that does not have an explicit type_id. +template <class T> struct is_unknown_integer { + static const bool value = !has_type_id<T>::value && is_integral<T>::value; +}; + +template<class T, class = typename enable_if<is_unknown_integer<T>::value>::type> +struct known_integer : public integer_type<sizeof(T), is_signed<T>::value> {}; + +// Helper base for SFINAE templates. +struct sfinae { + typedef char yes; + typedef double no; + struct any_t { + template < typename T > any_t(T const&); + }; +}; + +template <class From, class To> struct is_convertible : public sfinae { + static yes test(const To&); + static no test(...); + static const From& from; + // Windows compilers warn about data-loss caused by legal conversions. We + // can't use static_cast because that will cause a hard error instead of + // letting SFINAE overload resolution select the test(...) overload. +#ifdef _WIN32 +#pragma warning( push ) +#pragma warning( disable : 4244 ) +#endif + static bool const value = sizeof(test(from)) == sizeof(yes); +#ifdef _WIN32 +#pragma warning( pop ) +#endif +}; + +} // internal +} // proton + +#endif // PROTON_INTERNAL_TYPE_TRAITS_HPP --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org