From 85f4d7d0256ce6d60363fc563932ebd4284dce67 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sat, 10 Aug 2013 08:32:02 -0700 Subject: [PATCH] Move some classes into their own files --- Builds/VisualStudio2012/beast.vcxproj | 4 + Builds/VisualStudio2012/beast.vcxproj.filters | 15 + modules/beast_asio/basics/beast_BufferType.h | 100 +++++++ .../beast_asio/basics/beast_CompletionCall.h | 75 +++++ modules/beast_asio/basics/beast_ErrorCall.h | 84 ++++++ .../beast_asio/basics/beast_TransferCall.h | 81 ++++++ modules/beast_asio/beast_asio.h | 5 + modules/beast_asio/sockets/beast_Socket.cpp | 12 +- modules/beast_asio/sockets/beast_SocketBase.h | 261 ------------------ 9 files changed, 370 insertions(+), 267 deletions(-) create mode 100644 modules/beast_asio/basics/beast_BufferType.h create mode 100644 modules/beast_asio/basics/beast_CompletionCall.h create mode 100644 modules/beast_asio/basics/beast_ErrorCall.h create mode 100644 modules/beast_asio/basics/beast_TransferCall.h diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj index eca86d367f..78d0e2141f 100644 --- a/Builds/VisualStudio2012/beast.vcxproj +++ b/Builds/VisualStudio2012/beast.vcxproj @@ -69,6 +69,10 @@ + + + + diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters index 52c594a7a1..2846fd9748 100644 --- a/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Builds/VisualStudio2012/beast.vcxproj.filters @@ -155,6 +155,9 @@ {c4a7b6bb-88ec-4ff1-bc56-7c432a467500} + + {ccdc0c8e-f77a-486e-ba2f-29c10ec97f18} + @@ -818,6 +821,18 @@ beast_asio\tests + + beast_asio\basics + + + beast_asio\basics + + + beast_asio\basics + + + beast_asio\basics + diff --git a/modules/beast_asio/basics/beast_BufferType.h b/modules/beast_asio/basics/beast_BufferType.h new file mode 100644 index 0000000000..24e71d7564 --- /dev/null +++ b/modules/beast_asio/basics/beast_BufferType.h @@ -0,0 +1,100 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_BUFFERTYPE_H_INCLUDED +#define BEAST_BUFFERTYPE_H_INCLUDED + +/** Storage for a BufferSequence. + + Meets these requirements: + BufferSequence + ConstBufferSequence (when Buffer is mutable_buffer) + MutableBufferSequence (when Buffer is const_buffer) +*/ +template +class BufferType +{ +public: + typedef Buffer value_type; + typedef typename std::vector ::const_iterator const_iterator; + + BufferType () + : m_size (0) + { + } + + template + explicit BufferType (OtherBuffers const& buffers) + : m_size (0) + { + m_buffers.reserve (std::distance (buffers.begin (), buffers.end ())); + BOOST_FOREACH (typename OtherBuffers::value_type buffer, buffers) + { + m_size += boost::asio::buffer_size (buffer); + m_buffers.push_back (buffer); + } + } + + /** Determine the total size of all buffers. + This is faster than calling boost::asio::buffer_size. + */ + std::size_t size () const noexcept + { + return m_size; + } + + const_iterator begin () const noexcept + { + return m_buffers.begin (); + } + + const_iterator end () const noexcept + { + return m_buffers.end (); + } + + /** Retrieve a consumed BufferSequence. */ + BufferType consumed (std::size_t bytes) const + { + BufferType result; + result.m_buffers.reserve (m_buffers.size ()); + BOOST_FOREACH (Buffer buffer, m_buffers) + { + std::size_t const have = boost::asio::buffer_size (buffer); + std::size_t const reduce = std::min (bytes, have); + bytes -= reduce; + + if (have > reduce) + result.m_buffers.push_back (buffer + reduce); + } + return result; + } + +private: + std::size_t m_size; + std::vector m_buffers; +}; + +/** Meets the requirements of ConstBufferSequence */ +typedef BufferType ConstBuffers; + +/** Meets the requirements of MutableBufferSequence */ +typedef BufferType MutableBuffers; + +#endif diff --git a/modules/beast_asio/basics/beast_CompletionCall.h b/modules/beast_asio/basics/beast_CompletionCall.h new file mode 100644 index 0000000000..09a4dfa166 --- /dev/null +++ b/modules/beast_asio/basics/beast_CompletionCall.h @@ -0,0 +1,75 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_COMPLETIONCALL_H_INCLUDED +#define BEAST_COMPLETIONCALL_H_INCLUDED + +// Meets these requirements: +// +// CompletionHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/CompletionHandler.html +// +class CompletionCall +{ +public: + typedef void result_type; + + template + CompletionCall (BOOST_ASIO_MOVE_ARG(Handler) handler) + : m_call (new CallType (BOOST_ASIO_MOVE_CAST(Handler)(handler))) + { + } + + CompletionCall (CompletionCall const& other) + : m_call (other.m_call) + { + } + + void operator() () + { + (*m_call) (); + } + +private: + struct Call : SharedObject, LeakChecked + { + virtual void operator() () = 0; + }; + + template + struct CallType : Call + { + CallType (BOOST_ASIO_MOVE_ARG(Handler) handler) + : m_handler (handler) + { + } + + void operator() () + { + m_handler (); + } + + Handler m_handler; + }; + +private: + SharedObjectPtr m_call; +}; + +#endif diff --git a/modules/beast_asio/basics/beast_ErrorCall.h b/modules/beast_asio/basics/beast_ErrorCall.h new file mode 100644 index 0000000000..1f9a5d3cbc --- /dev/null +++ b/modules/beast_asio/basics/beast_ErrorCall.h @@ -0,0 +1,84 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_ERRORCALL_H_INCLUDED +#define BEAST_ERRORCALL_H_INCLUDED + +// Meets these requirements: +// +// AcceptHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AcceptHandler.html +// +// ConnectHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ConnectHandler.html +// +// ShutdownHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ShutdownHandler.html +// +// HandshakeHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/HandshakeHandler.html +// +class ErrorCall +{ +public: + typedef void result_type; + + template + ErrorCall (BOOST_ASIO_MOVE_ARG(Handler) handler) + : m_call (new CallType (BOOST_ASIO_MOVE_CAST(Handler)(handler))) + { + } + + ErrorCall (ErrorCall const& other) + : m_call (other.m_call) + { + } + + void operator() (boost::system::error_code const& ec) + { + (*m_call) (ec); + } + +private: + struct Call : SharedObject, LeakChecked + { + virtual void operator() (boost::system::error_code const&) = 0; + }; + + template + struct CallType : Call + { + CallType (BOOST_ASIO_MOVE_ARG(Handler) handler) + : m_handler (handler) + { + } + + void operator() (boost::system::error_code const& ec) + { + m_handler (ec); + } + + Handler m_handler; + }; + +private: + SharedObjectPtr m_call; +}; + +#endif diff --git a/modules/beast_asio/basics/beast_TransferCall.h b/modules/beast_asio/basics/beast_TransferCall.h new file mode 100644 index 0000000000..6ec9a1e2b7 --- /dev/null +++ b/modules/beast_asio/basics/beast_TransferCall.h @@ -0,0 +1,81 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_TRANSFERCALL_H_INCLUDED +#define BEAST_TRANSFERCALL_H_INCLUDED + +// Meets these requirements +// +// ReadHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ReadHandler.html +// +// WriteHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/WriteHandler.html +// +// BUfferedHandshakeHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/BufferedHandshakeHandler.html +// +class TransferCall +{ +public: + typedef void result_type; + + template + TransferCall (BOOST_ASIO_MOVE_ARG(Handler) handler) + : m_call (new CallType (BOOST_ASIO_MOVE_CAST(Handler)(handler))) + { + } + + TransferCall (TransferCall const& other) + : m_call (other.m_call) + { + } + + void operator() (boost::system::error_code const& ec, std::size_t bytes_transferred) + { + (*m_call) (ec, bytes_transferred); + } + +private: + struct Call : SharedObject, LeakChecked + { + virtual void operator() (boost::system::error_code const&, std::size_t) = 0; + }; + + template + struct CallType : Call + { + CallType (BOOST_ASIO_MOVE_ARG(Handler) handler) + : m_handler (handler) + { + } + + void operator() (boost::system::error_code const& ec, std::size_t bytes_transferred) + { + m_handler (ec, bytes_transferred); + } + + Handler m_handler; + }; + +private: + SharedObjectPtr m_call; +}; + +#endif diff --git a/modules/beast_asio/beast_asio.h b/modules/beast_asio/beast_asio.h index f8f52d8415..159190c76e 100644 --- a/modules/beast_asio/beast_asio.h +++ b/modules/beast_asio/beast_asio.h @@ -48,6 +48,11 @@ namespace beast // Order matters +#include "basics/beast_BufferType.h" +#include "basics/beast_CompletionCall.h" +#include "basics/beast_ErrorCall.h" +#include "basics/beast_TransferCall.h" + #include "sockets/beast_SocketBase.h" #include "sockets/beast_Socket.h" #include "sockets/beast_SocketInterface.h" diff --git a/modules/beast_asio/sockets/beast_Socket.cpp b/modules/beast_asio/sockets/beast_Socket.cpp index 5849680776..ef07e40dc2 100644 --- a/modules/beast_asio/sockets/beast_Socket.cpp +++ b/modules/beast_asio/sockets/beast_Socket.cpp @@ -54,7 +54,7 @@ boost::system::error_code Socket::accept (Socket&, boost::system::error_code& ec return pure_virtual (ec); } -BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::ErrorCall, void (boost::system::error_code)) +BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code)) Socket::async_accept (Socket&, BOOST_ASIO_MOVE_ARG(ErrorCall) handler) { #if BEAST_ASIO_HAS_FUTURE_RETURNS @@ -120,7 +120,7 @@ std::size_t Socket::write_some (ConstBuffers const&, boost::system::error_code& return 0; } -BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::TransferCall, void (boost::system::error_code, std::size_t)) +BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t)) Socket::async_read_some (MutableBuffers const&, BOOST_ASIO_MOVE_ARG(TransferCall) handler) { #if BEAST_ASIO_HAS_FUTURE_RETURNS @@ -138,7 +138,7 @@ Socket::async_read_some (MutableBuffers const&, BOOST_ASIO_MOVE_ARG(TransferCall #endif } -BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::TransferCall, void (boost::system::error_code, std::size_t)) +BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t)) Socket::async_write_some (ConstBuffers const&, BOOST_ASIO_MOVE_ARG(TransferCall) handler) { #if BEAST_ASIO_HAS_FUTURE_RETURNS @@ -169,7 +169,7 @@ boost::system::error_code Socket::handshake (handshake_type, boost::system::erro return pure_virtual (ec); } -BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::ErrorCall, void (boost::system::error_code)) +BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code)) Socket::async_handshake (handshake_type, BOOST_ASIO_MOVE_ARG(ErrorCall) handler) { #if BEAST_ASIO_HAS_FUTURE_RETURNS @@ -199,7 +199,7 @@ boost::system::error_code Socket::handshake (handshake_type, return pure_virtual (ec); } -BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::TransferCall, void (boost::system::error_code, std::size_t)) +BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t)) Socket::async_handshake (handshake_type, ConstBuffers const&, BOOST_ASIO_MOVE_ARG(TransferCall) handler) { @@ -227,7 +227,7 @@ boost::system::error_code Socket::shutdown (boost::system::error_code& ec) return pure_virtual (ec); } -BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::ErrorCall, void (boost::system::error_code)) +BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code)) Socket::async_shutdown (BOOST_ASIO_MOVE_ARG(ErrorCall) handler) { #if BEAST_ASIO_HAS_FUTURE_RETURNS diff --git a/modules/beast_asio/sockets/beast_SocketBase.h b/modules/beast_asio/sockets/beast_SocketBase.h index 07527d69ff..f144535415 100644 --- a/modules/beast_asio/sockets/beast_SocketBase.h +++ b/modules/beast_asio/sockets/beast_SocketBase.h @@ -30,266 +30,6 @@ protected: static boost::system::error_code pure_virtual (boost::system::error_code& ec); protected: - //-------------------------------------------------------------------------- - // - // Buffers - // - //-------------------------------------------------------------------------- - - /** Storage for a BufferSequence. - - Meets these requirements: - BufferSequence - ConstBufferSequence (when Buffer is mutable_buffer) - MutableBufferSequence (when Buffer is const_buffer) - */ - template - class Buffers - { - public: - typedef Buffer value_type; - typedef typename std::vector ::const_iterator const_iterator; - - Buffers () - : m_size (0) - { - } - - template - explicit Buffers (OtherBuffers const& buffers) - : m_size (0) - { - m_buffers.reserve (std::distance (buffers.begin (), buffers.end ())); - BOOST_FOREACH (typename OtherBuffers::value_type buffer, buffers) - { - m_size += boost::asio::buffer_size (buffer); - m_buffers.push_back (buffer); - } - } - - /** Determine the total size of all buffers. - This is faster than calling boost::asio::buffer_size. - */ - std::size_t size () const noexcept - { - return m_size; - } - - const_iterator begin () const noexcept - { - return m_buffers.begin (); - } - - const_iterator end () const noexcept - { - return m_buffers.end (); - } - - /** Retrieve a consumed BufferSequence. */ - Buffers consumed (std::size_t bytes) const - { - Buffers result; - result.m_buffers.reserve (m_buffers.size ()); - BOOST_FOREACH (Buffer buffer, m_buffers) - { - std::size_t const have = boost::asio::buffer_size (buffer); - std::size_t const reduce = std::min (bytes, have); - bytes -= reduce; - - if (have > reduce) - result.m_buffers.push_back (buffer + reduce); - } - return result; - } - - private: - std::size_t m_size; - std::vector m_buffers; - }; - - /** Meets the requirements of ConstBufferSequence */ - typedef Buffers ConstBuffers; - - /** Meets the requirements of MutableBufferSequence */ - typedef Buffers MutableBuffers; - - //-------------------------------------------------------------------------- - // - // Handler abstractions - // - //-------------------------------------------------------------------------- - - // Meets these requirements: - // - // CompletionHandler - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/CompletionHandler.html - // - class CompletionCall - { - public: - typedef void result_type; - - template - CompletionCall (BOOST_ASIO_MOVE_ARG(Handler) handler) - : m_call (new CallType (BOOST_ASIO_MOVE_CAST(Handler)(handler))) - { - } - - CompletionCall (CompletionCall const& other) - : m_call (other.m_call) - { - } - - void operator() () - { - (*m_call) (); - } - - private: - struct Call : SharedObject, LeakChecked - { - virtual void operator() () = 0; - }; - - template - struct CallType : Call - { - CallType (BOOST_ASIO_MOVE_ARG(Handler) handler) - : m_handler (handler) - { - } - - void operator() () - { - m_handler (); - } - - Handler m_handler; - }; - - private: - SharedObjectPtr m_call; - }; - - // Meets these requirements: - // - // AcceptHandler - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AcceptHandler.html - // - // ConnectHandler - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ConnectHandler.html - // - // ShutdownHandler - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ShutdownHandler.html - // - // HandshakeHandler - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/HandshakeHandler.html - // - class ErrorCall - { - public: - typedef void result_type; - - template - ErrorCall (BOOST_ASIO_MOVE_ARG(Handler) handler) - : m_call (new CallType (BOOST_ASIO_MOVE_CAST(Handler)(handler))) - { - } - - ErrorCall (ErrorCall const& other) - : m_call (other.m_call) - { - } - - void operator() (boost::system::error_code const& ec) - { - (*m_call) (ec); - } - - private: - struct Call : SharedObject, LeakChecked - { - virtual void operator() (boost::system::error_code const&) = 0; - }; - - template - struct CallType : Call - { - CallType (BOOST_ASIO_MOVE_ARG(Handler) handler) - : m_handler (handler) - { - } - - void operator() (boost::system::error_code const& ec) - { - m_handler (ec); - } - - Handler m_handler; - }; - - private: - SharedObjectPtr m_call; - }; - - // Meets these requirements - // - // ReadHandler - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ReadHandler.html - // - // WriteHandler - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/WriteHandler.html - // - // BUfferedHandshakeHandler - // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/BufferedHandshakeHandler.html - // - class TransferCall - { - public: - typedef void result_type; - - template - TransferCall (BOOST_ASIO_MOVE_ARG(Handler) handler) - : m_call (new CallType (BOOST_ASIO_MOVE_CAST(Handler)(handler))) - { - } - - TransferCall (TransferCall const& other) - : m_call (other.m_call) - { - } - - void operator() (boost::system::error_code const& ec, std::size_t bytes_transferred) - { - (*m_call) (ec, bytes_transferred); - } - - private: - struct Call : SharedObject, LeakChecked - { - virtual void operator() (boost::system::error_code const&, std::size_t) = 0; - }; - - template - struct CallType : Call - { - CallType (BOOST_ASIO_MOVE_ARG(Handler) handler) - : m_handler (handler) - { - } - - void operator() (boost::system::error_code const& ec, std::size_t bytes_transferred) - { - m_handler (ec, bytes_transferred); - } - - Handler m_handler; - }; - - private: - SharedObjectPtr m_call; - }; - /** Called when the underlying object does not support the interface. */ void throw_error (boost::system::error_code const& ec) { @@ -298,5 +38,4 @@ protected: } }; - #endif