diff --git a/examples/client/basic_client.vcxproj b/examples/client/basic_client.vcxproj index 4b18278..3a3778e 100644 --- a/examples/client/basic_client.vcxproj +++ b/examples/client/basic_client.vcxproj @@ -70,7 +70,7 @@ - ..\..\include;..\..\third\msgpack\include;$(IncludePath) + ..\..\include;..\..\thirdparty\msgpack-c\include;$(IncludePath) ..\..\include;..\..\third\msgpack\include;$(IncludePath) diff --git a/examples/server/basic_server.vcxproj b/examples/server/basic_server.vcxproj index 7d1b7de..25ff6c7 100644 --- a/examples/server/basic_server.vcxproj +++ b/examples/server/basic_server.vcxproj @@ -76,8 +76,8 @@ ..\..\include;..\..\third\msgpack\include;$(IncludePath) - ..\..\include;..\..\third\msgpack\include;D:\boost_1_73_0;$(IncludePath) - D:\boost_1_73_0\lib64-msvc-14.2;$(LibraryPath) + ..\..\include;..\..\thirdparty\msgpack-c\include;$(IncludePath) + $(LibraryPath) ..\..\include;..\..\third\msgpack\include;$(IncludePath) diff --git a/examples/server/main.cpp b/examples/server/main.cpp index 249baf0..fbe3210 100644 --- a/examples/server/main.cpp +++ b/examples/server/main.cpp @@ -7,6 +7,13 @@ using namespace rpc_service; struct dummy{ int add(rpc_conn conn, int a, int b) { + auto shared_conn = conn.lock(); + if (shared_conn) { + shared_conn->set_user_data(std::string("aa")); + auto s = conn.lock()->get_user_data(); + std::cout << s << '\n'; //aa + } + return a + b; } }; diff --git a/include/rest_rpc/connection.h b/include/rest_rpc/connection.h index 97230d1..f6885cb 100644 --- a/include/rest_rpc/connection.h +++ b/include/rest_rpc/connection.h @@ -9,6 +9,7 @@ #include "const_vars.h" #include "router.h" #include "cplusplus_14.h" +#include "nonstd_any.hpp" using boost::asio::ip::tcp; @@ -73,6 +74,16 @@ namespace rest_rpc { int64_t conn_id() const { return conn_id_; } + template + void set_user_data(const T &data) { + user_data_ = data; + } + + template + T get_user_data() { + return nonstd::any_cast(user_data_); + } + const std::vector& body() const { return body_; } @@ -364,6 +375,7 @@ namespace rest_rpc { std::deque write_queue_; std::function)> callback_; router& router_; + nonstd::any user_data_; }; } // namespace rpc_service } // namespace rest_rpc diff --git a/include/rest_rpc/nonstd_any.hpp b/include/rest_rpc/nonstd_any.hpp new file mode 100644 index 0000000..622d7d4 --- /dev/null +++ b/include/rest_rpc/nonstd_any.hpp @@ -0,0 +1,721 @@ +// +// Copyright (c) 2016-2018 Martin Moene +// +// https://github.com/martinmoene/any-lite +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#ifndef NONSTD_ANY_LITE_HPP +#define NONSTD_ANY_LITE_HPP + +#define any_lite_MAJOR 0 +#define any_lite_MINOR 4 +#define any_lite_PATCH 0 + +#define any_lite_VERSION any_STRINGIFY(any_lite_MAJOR) "." any_STRINGIFY(any_lite_MINOR) "." any_STRINGIFY(any_lite_PATCH) + +#define any_STRINGIFY( x ) any_STRINGIFY_( x ) +#define any_STRINGIFY_( x ) #x + +// any-lite configuration: + +#define any_ANY_DEFAULT 0 +#define any_ANY_NONSTD 1 +#define any_ANY_STD 2 + +// tweak header support: + +#ifdef __has_include +# if __has_include() +# include +# endif +#define any_HAVE_TWEAK_HEADER 1 +#else +#define any_HAVE_TWEAK_HEADER 0 +//# pragma message("any.hpp: Note: Tweak header not supported.") +#endif + +// any selection and configuration: + +#if !defined( any_CONFIG_SELECT_ANY ) +# define any_CONFIG_SELECT_ANY ( any_HAVE_STD_ANY ? any_ANY_STD : any_ANY_NONSTD ) +#endif + +// Control presence of exception handling (try and auto discover): + +#ifndef any_CONFIG_NO_EXCEPTIONS +# if _MSC_VER +# include // for _HAS_EXCEPTIONS +# endif +# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS) +# define any_CONFIG_NO_EXCEPTIONS 0 +# else +# define any_CONFIG_NO_EXCEPTIONS 1 +# endif +#endif + +// C++ language version detection (C++20 is speculative): +// Note: VC14.0/1900 (VS2015) lacks too much from C++14. + +#ifndef any_CPLUSPLUS +# if defined(_MSVC_LANG ) && !defined(__clang__) +# define any_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) +# else +# define any_CPLUSPLUS __cplusplus +# endif +#endif + +#define any_CPP98_OR_GREATER ( any_CPLUSPLUS >= 199711L ) +#define any_CPP11_OR_GREATER ( any_CPLUSPLUS >= 201103L ) +#define any_CPP14_OR_GREATER ( any_CPLUSPLUS >= 201402L ) +#define any_CPP17_OR_GREATER ( any_CPLUSPLUS >= 201703L ) +#define any_CPP20_OR_GREATER ( any_CPLUSPLUS >= 202000L ) + +// Use C++17 std::any if available and requested: + +#if any_CPP17_OR_GREATER && defined(__has_include ) +# if __has_include( ) +# define any_HAVE_STD_ANY 1 +# else +# define any_HAVE_STD_ANY 0 +# endif +#else +# define any_HAVE_STD_ANY 0 +#endif + +#define any_USES_STD_ANY ( (any_CONFIG_SELECT_ANY == any_ANY_STD) || ((any_CONFIG_SELECT_ANY == any_ANY_DEFAULT) && any_HAVE_STD_ANY) ) + +// +// in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite: +// + +#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES +#define nonstd_lite_HAVE_IN_PLACE_TYPES 1 + +// C++17 std::in_place in : + +#if any_CPP17_OR_GREATER + +#include + +namespace nonstd { + + using std::in_place; + using std::in_place_type; + using std::in_place_index; + using std::in_place_t; + using std::in_place_type_t; + using std::in_place_index_t; + +#define nonstd_lite_in_place_t( T) std::in_place_t +#define nonstd_lite_in_place_type_t( T) std::in_place_type_t +#define nonstd_lite_in_place_index_t(K) std::in_place_index_t + +#define nonstd_lite_in_place( T) std::in_place_t{} +#define nonstd_lite_in_place_type( T) std::in_place_type_t{} +#define nonstd_lite_in_place_index(K) std::in_place_index_t{} + +} // namespace nonstd + +#else // any_CPP17_OR_GREATER + +#include + +namespace nonstd { + namespace detail { + + template< class T > + struct in_place_type_tag {}; + + template< std::size_t K > + struct in_place_index_tag {}; + + } // namespace detail + + struct in_place_t {}; + + template< class T > + inline in_place_t in_place(detail::in_place_type_tag = detail::in_place_type_tag()) + { + return in_place_t(); + } + + template< std::size_t K > + inline in_place_t in_place(detail::in_place_index_tag = detail::in_place_index_tag()) + { + return in_place_t(); + } + + template< class T > + inline in_place_t in_place_type(detail::in_place_type_tag = detail::in_place_type_tag()) + { + return in_place_t(); + } + + template< std::size_t K > + inline in_place_t in_place_index(detail::in_place_index_tag = detail::in_place_index_tag()) + { + return in_place_t(); + } + + // mimic templated typedef: + +#define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) +#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) +#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag ) + +#define nonstd_lite_in_place( T) nonstd::in_place_type +#define nonstd_lite_in_place_type( T) nonstd::in_place_type +#define nonstd_lite_in_place_index(K) nonstd::in_place_index + +} // namespace nonstd + +#endif // any_CPP17_OR_GREATER +#endif // nonstd_lite_HAVE_IN_PLACE_TYPES + +// +// Using std::any: +// + +#if any_USES_STD_ANY + +#include +#include + +namespace nonstd { + + using std::any; + using std::any_cast; + using std::make_any; + using std::swap; + using std::bad_any_cast; +} + +#else // any_USES_STD_ANY + +#include + +// Compiler versions: +// +// MSVC++ 6.0 _MSC_VER == 1200 any_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0) +// MSVC++ 7.0 _MSC_VER == 1300 any_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002) +// MSVC++ 7.1 _MSC_VER == 1310 any_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003) +// MSVC++ 8.0 _MSC_VER == 1400 any_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005) +// MSVC++ 9.0 _MSC_VER == 1500 any_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008) +// MSVC++ 10.0 _MSC_VER == 1600 any_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010) +// MSVC++ 11.0 _MSC_VER == 1700 any_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012) +// MSVC++ 12.0 _MSC_VER == 1800 any_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013) +// MSVC++ 14.0 _MSC_VER == 1900 any_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015) +// MSVC++ 14.1 _MSC_VER >= 1910 any_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017) +// MSVC++ 14.2 _MSC_VER >= 1920 any_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019) + +#if defined(_MSC_VER ) && !defined(__clang__) +# define any_COMPILER_MSVC_VER (_MSC_VER ) +# define any_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) ) +#else +# define any_COMPILER_MSVC_VER 0 +# define any_COMPILER_MSVC_VERSION 0 +#endif + +#define any_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) ) + +#if defined(__clang__) +# define any_COMPILER_CLANG_VERSION any_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) +#else +# define any_COMPILER_CLANG_VERSION 0 +#endif + +#if defined(__GNUC__) && !defined(__clang__) +# define any_COMPILER_GNUC_VERSION any_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#else +# define any_COMPILER_GNUC_VERSION 0 +#endif + +// half-open range [lo..hi): +//#define any_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) + +// Presence of language and library features: + +#define any_HAVE( feature ) ( any_HAVE_##feature ) + +#ifdef _HAS_CPP0X +# define any_HAS_CPP0X _HAS_CPP0X +#else +# define any_HAS_CPP0X 0 +#endif + +#define any_CPP11_90 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1500) +#define any_CPP11_100 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1600) +#define any_CPP11_120 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1800) +#define any_CPP11_140 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1900) + +#define any_CPP14_000 (any_CPP14_OR_GREATER) +#define any_CPP17_000 (any_CPP17_OR_GREATER) + +// Presence of C++11 language features: + +#define any_HAVE_CONSTEXPR_11 any_CPP11_140 +#define any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG \ + any_CPP11_120 +#define any_HAVE_INITIALIZER_LIST any_CPP11_120 +#define any_HAVE_NOEXCEPT any_CPP11_140 +#define any_HAVE_NULLPTR any_CPP11_100 +#define any_HAVE_TYPE_TRAITS any_CPP11_90 +#define any_HAVE_STATIC_ASSERT any_CPP11_100 +#define any_HAVE_ADD_CONST any_CPP11_90 +#define any_HAVE_REMOVE_REFERENCE any_CPP11_90 + +#define any_HAVE_TR1_ADD_CONST (!! any_COMPILER_GNUC_VERSION ) +#define any_HAVE_TR1_REMOVE_REFERENCE (!! any_COMPILER_GNUC_VERSION ) +#define any_HAVE_TR1_TYPE_TRAITS (!! any_COMPILER_GNUC_VERSION ) + +// Presence of C++14 language features: + +#define any_HAVE_CONSTEXPR_14 any_CPP14_000 + +// Presence of C++17 language features: + +#define any_HAVE_NODISCARD any_CPP17_000 + +// Presence of C++ language features: + +#if any_HAVE_CONSTEXPR_11 +# define any_constexpr constexpr +#else +# define any_constexpr /*constexpr*/ +#endif + +#if any_HAVE_CONSTEXPR_14 +# define any_constexpr14 constexpr +#else +# define any_constexpr14 /*constexpr*/ +#endif + +#if any_HAVE_NOEXCEPT +# define any_noexcept noexcept +#else +# define any_noexcept /*noexcept*/ +#endif + +#if any_HAVE_NULLPTR +# define any_nullptr nullptr +#else +# define any_nullptr NULL +#endif + +#if any_HAVE_NODISCARD +# define any_nodiscard [[nodiscard]] +#else +# define any_nodiscard /*[[nodiscard]]*/ +#endif + +// additional includes: + +#if any_CONFIG_NO_EXCEPTIONS +# include +#else +# include +#endif + +#if ! any_HAVE_NULLPTR +# include +#endif + +#if any_HAVE_INITIALIZER_LIST +# include +#endif + +#if any_HAVE_TYPE_TRAITS +# include +#elif any_HAVE_TR1_TYPE_TRAITS +# include +#endif + +// Method enabling + +#if any_CPP11_OR_GREATER + +#define any_REQUIRES_0(...) \ + template< bool B = (__VA_ARGS__), typename std::enable_if::type = 0 > + +#define any_REQUIRES_T(...) \ + , typename std::enable_if< (__VA_ARGS__), int >::type = 0 + +#define any_REQUIRES_R(R, ...) \ + typename std::enable_if<__VA_ARGS__, R>::type + +#define any_REQUIRES_A(...) \ + , typename std::enable_if<__VA_ARGS__, void*>::type = nullptr + +#endif + +// +// any: +// + +namespace nonstd { + namespace any_lite { + + // C++11 emulation: + + namespace std11 { + +#if any_HAVE_ADD_CONST + + using std::add_const; + +#elif any_HAVE_TR1_ADD_CONST + + using std::tr1::add_const; + +#else + + template< class T > struct add_const { typedef const T type; }; + +#endif // any_HAVE_ADD_CONST + +#if any_HAVE_REMOVE_REFERENCE + + using std::remove_reference; + +#elif any_HAVE_TR1_REMOVE_REFERENCE + + using std::tr1::remove_reference; + +#else + + template< class T > struct remove_reference { typedef T type; }; + template< class T > struct remove_reference { typedef T type; }; + +#endif // any_HAVE_REMOVE_REFERENCE + + } // namespace std11 + + namespace detail { + + // for any_REQUIRES_T + + /*enum*/ class enabler {}; + + } // namespace detail + +#if ! any_CONFIG_NO_EXCEPTIONS + + class bad_any_cast : public std::bad_cast + { + public: +#if any_CPP11_OR_GREATER + virtual const char* what() const any_noexcept +#else + virtual const char* what() const throw() +#endif + { + return "any-lite: bad any_cast"; + } + }; + +#endif // any_CONFIG_NO_EXCEPTIONS + + class any + { + public: + any_constexpr any() any_noexcept + : content(any_nullptr) + {} + + any(any const& other) + : content(other.content ? other.content->clone() : any_nullptr) + {} + +#if any_CPP11_OR_GREATER + + any(any&& other) any_noexcept + : content(std::move(other.content)) + { + other.content = any_nullptr; + } + + template< + class ValueType, class T = typename std::decay::type + any_REQUIRES_T(!std::is_same::value) + > + any(ValueType&& value) any_noexcept + : content(new holder(std::forward(value))) + {} + + template< + class T, class... Args + any_REQUIRES_T(std::is_constructible::value) + > + explicit any(nonstd_lite_in_place_type_t(T), Args&&... args) + : content(new holder(T(std::forward(args)...))) + {} + + template< + class T, class U, class... Args + any_REQUIRES_T(std::is_constructible&, Args&&...>::value) + > + explicit any(nonstd_lite_in_place_type_t(T), std::initializer_list il, Args&&... args) + : content(new holder(T(il, std::forward(args)...))) + {} + +#else + + template< class ValueType > + any(ValueType const& value) + : content(new holder(value)) + {} + +#endif // any_CPP11_OR_GREATER + + ~any() + { + reset(); + } + + any& operator=(any const& other) + { + any(other).swap(*this); + return *this; + } + +#if any_CPP11_OR_GREATER + + any& operator=(any&& other) any_noexcept + { + any(std::move(other)).swap(*this); + return *this; + } + + template< + class ValueType, class T = typename std::decay::type + any_REQUIRES_T(!std::is_same::value) + > + any& operator=(T&& value) + { + any(std::move(value)).swap(*this); + return *this; + } + + template< class T, class... Args > + void emplace(Args && ... args) + { + any(T(std::forward(args)...)).swap(*this); + } + + template< + class T, class U, class... Args + any_REQUIRES_T(std::is_constructible&, Args&&...>::value) + > + void emplace(std::initializer_list il, Args&&... args) + { + any(T(il, std::forward(args)...)).swap(*this); + } + +#else + + template< class ValueType > + any& operator=(ValueType const& value) + { + any(value).swap(*this); + return *this; + } + +#endif // any_CPP11_OR_GREATER + + void reset() any_noexcept + { + delete content; content = any_nullptr; + } + + void swap(any& other) any_noexcept + { + std::swap(content, other.content); + } + + bool has_value() const any_noexcept + { + return content != any_nullptr; + } + + const std::type_info& type() const any_noexcept + { + return has_value() ? content->type() : typeid(void); + } + + // + // non-standard: + // + + template< class ValueType > + const ValueType* to_ptr() const + { + return &(static_cast *>(content)->held); + } + + template< class ValueType > + ValueType* to_ptr() + { + return &(static_cast *>(content)->held); + } + + private: + class placeholder + { + public: + virtual ~placeholder() + { + } + + virtual std::type_info const& type() const = 0; + + virtual placeholder* clone() const = 0; + }; + + template< typename ValueType > + class holder : public placeholder + { + public: + holder(ValueType const& value) + : held(value) + {} + +#if any_CPP11_OR_GREATER + holder(ValueType&& value) + : held(std::move(value)) + {} +#endif + + virtual std::type_info const& type() const + { + return typeid(ValueType); + } + + virtual placeholder* clone() const + { + return new holder(held); + } + + ValueType held; + }; + + placeholder* content; + }; + + inline void swap(any& x, any& y) any_noexcept + { + x.swap(y); + } + +#if any_CPP11_OR_GREATER + + template< class T, class ...Args > + inline any make_any(Args&& ...args) + { + return any(nonstd_lite_in_place_type(T), std::forward(args)...); + } + + template< class T, class U, class ...Args > + inline any make_any(std::initializer_list il, Args&& ...args) + { + return any(nonstd_lite_in_place_type(T), il, std::forward(args)...); + } + +#endif // any_CPP11_OR_GREATER + + template< + class ValueType +#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG + // any_REQUIRES_T(...) Allow for VC120 (VS2013): + , typename = typename std::enable_if< (std::is_reference::value || std::is_copy_constructible::value), nonstd::any_lite::detail::enabler >::type +#endif + > + any_nodiscard inline ValueType any_cast(any const& operand) + { + const ValueType* result = any_cast::type >::type>(&operand); + +#if any_CONFIG_NO_EXCEPTIONS + assert(result); +#else + if (!result) + { + throw bad_any_cast(); + } +#endif + + return *result; + } + + template< + class ValueType +#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG + // any_REQUIRES_T(...) Allow for VC120 (VS2013): + , typename = typename std::enable_if< (std::is_reference::value || std::is_copy_constructible::value), nonstd::any_lite::detail::enabler >::type +#endif + > + any_nodiscard inline ValueType any_cast(any& operand) + { + const ValueType* result = any_cast::type>(&operand); + +#if any_CONFIG_NO_EXCEPTIONS + assert(result); +#else + if (!result) + { + throw bad_any_cast(); + } +#endif + + return *result; + } + +#if any_CPP11_OR_GREATER + + template< + class ValueType +#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG + any_REQUIRES_T(std::is_reference::value || std::is_copy_constructible::value) +#endif + > + any_nodiscard inline ValueType any_cast(any&& operand) + { + const ValueType* result = any_cast::type>(&operand); + +#if any_CONFIG_NO_EXCEPTIONS + assert(result); +#else + if (!result) + { + throw bad_any_cast(); + } +#endif + + return *result; + } + +#endif // any_CPP11_OR_GREATER + + template< class ValueType > + any_nodiscard inline ValueType const* any_cast(any const* operand) any_noexcept + { + return operand != any_nullptr && operand->type() == typeid(ValueType) ? operand->to_ptr() : any_nullptr; + } + + template + any_nodiscard inline ValueType* any_cast(any* operand) any_noexcept + { + return operand != any_nullptr && operand->type() == typeid(ValueType) ? operand->to_ptr() : any_nullptr; + } + + } // namespace any_lite + + using namespace any_lite; + +} // namespace nonstd + +#endif // any_USES_STD_ANY + +#endif // NONSTD_ANY_LITE_HPP \ No newline at end of file