Created
September 23, 2012 14:08
-
-
Save dimitarcl/3771331 to your computer and use it in GitHub Desktop.
A twist on PImpl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
?GetPort@HTTPServer@@QBEGXZ PROC ; HTTPServer::GetPort, COMDAT | |
; _this$ = ecx | |
mov ax, WORD PTR [ecx] | |
ret 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "HTTPServer.h" | |
#include "HTTPServerImpl.h" | |
HTTPServer::HTTPServer(unsigned short port) | |
: m_Impl(port) | |
{ | |
} | |
HTTPServer::~HTTPServer() | |
{ | |
} | |
unsigned short HTTPServer::GetPort() const | |
{ | |
return m_Impl->GetPort(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Impl.h" | |
class HTTPServerImpl; | |
class HTTPServer | |
{ | |
public: | |
HTTPServer(unsigned short port); | |
~HTTPServer(); | |
unsigned short GetPort() const; | |
private: | |
Impl<HTTPServerImpl, 8> m_Impl; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
?GetPort@HTTPServer@@QBEGXZ PROC ; HTTPServer::GetPort, COMDAT | |
; _this$ = ecx | |
mov eax, DWORD PTR [ecx] | |
mov ax, WORD PTR [eax] | |
ret 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "HTTPServerClassic.h" | |
#include "HTTPServerImpl.h" | |
HTTPServer::HTTPServer(unsigned short port) | |
: m_Impl(new HTTPServerImpl(port)) | |
{ | |
} | |
HTTPServer::~HTTPServer() | |
{ | |
} | |
unsigned short HTTPServer::GetPort() const | |
{ | |
return m_Impl->GetPort(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <memory> | |
class HTTPServerImpl; | |
class HTTPServer | |
{ | |
public: | |
HTTPServer(unsigned short port); | |
~HTTPServer(); | |
unsigned short GetPort() const; | |
private: | |
std::unique_ptr<HTTPServerImpl> m_Impl; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
class HTTPServerImpl | |
{ | |
public: | |
HTTPServerImpl(unsigned short port) | |
: m_Port(port) | |
{ | |
} | |
unsigned short GetPort() const | |
{ | |
return m_Port; | |
} | |
private: | |
unsigned short m_Port; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <new> | |
#include <utility> | |
// Visual Studio 2010 does not support std::max_align_t, | |
// so use an arbitrary default and leave it for clients to specify better value | |
template <typename T, size_t size, size_t alignment = sizeof(unsigned long long)> | |
class Impl | |
{ | |
public: | |
Impl() | |
{ | |
new (Get()) T; | |
} | |
template <typename Arg1> | |
Impl(Arg1&& arg1) | |
{ | |
new (Get()) T(std::forward<Arg1>(arg1)); | |
} | |
template <typename Arg1, typename Arg2> | |
Impl(Arg1&& arg1, Arg2&& arg2) | |
{ | |
new (Get()) T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2)); | |
} | |
Impl& operator=(const Impl& rhs) | |
{ | |
*Get() = *rhs.Get(); | |
} | |
Impl& operator=(Impl&& rhs) | |
{ | |
*Get() = std::move(*rhs.Get()); | |
} | |
~Impl() | |
{ | |
static_assert(sizeof(T) <= size, | |
"Implementation instance does not fit in the buffer"); | |
static_assert(alignment % std::alignment_of<T>::value == 0, | |
"Implementation instance has incompatible alignment requirements"); | |
Get()->~T(); | |
} | |
T* Get() | |
{ | |
return reinterpret_cast<T*>(&m_Buffer); | |
} | |
const T* Get() const | |
{ | |
return reinterpret_cast<const T*>(&m_Buffer); | |
} | |
T* operator->() | |
{ | |
return Get(); | |
} | |
const T* operator->() const | |
{ | |
return Get(); | |
} | |
private: | |
typedef typename std::aligned_storage<size, alignment>::type AlignedStorage; | |
AlignedStorage m_Buffer; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment