Skip to content

Commit

Permalink
Interconnect: make Emitter working with virtual bases on 32bit Windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
mosra committed Aug 28, 2018
1 parent c18a387 commit b83c116
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 5 deletions.
3 changes: 3 additions & 0 deletions doc/corrade-changelog.dox
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ namespace Corrade {
- Worked around a misoptimization of @ref Utility::Sha1 when using GCC 6 with
-O3 on Raspberry Pi Model 3 B+ (AArch64) (GCC 8 works properly again). See
[mosra/corrade#45](https://github.com/mosra/corrade/issues/45).
- It was not possible to use the @ref Interconnect::Emitter class with
virtual base classes on 32-bit Windows due to an incorrect assumption about
member function pointer sizes

@subsection corrade-changelog-latest-docs Documentation

Expand Down
10 changes: 9 additions & 1 deletion src/Corrade/Interconnect/Connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,15 @@ namespace Implementation {

class SignalData {
public:
enum: std::size_t { Size = 2*sizeof(void*)/sizeof(std::size_t) };
enum: std::size_t { Size =
#ifndef CORRADE_TARGET_WINDOWS
2*sizeof(void*)/sizeof(std::size_t)
#else
/* On MSVC, pointers to members with a virtual base class
are the biggest and have 16 bytes both on 32bit and 64bit. */
16/sizeof(std::size_t)
#endif
};

#ifndef CORRADE_MSVC2017_COMPATIBILITY
template<class Emitter, class ...Args> SignalData(typename Emitter::Signal(Emitter::*signal)(Args...)): data() {
Expand Down
8 changes: 4 additions & 4 deletions src/Corrade/Interconnect/Emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,8 @@ more information about connections.
@ref Emitter::signalConnectionCount()
*/
template<class EmitterObject, class Emitter, class ...Args> Connection connect(EmitterObject& emitter, Interconnect::Emitter::Signal(Emitter::*signal)(Args...), void(*slot)(Args...)) {
static_assert(sizeof(Interconnect::Emitter::Signal(Emitter::*)(Args...)) <= 2*sizeof(void*),
"Size of member function pointer is incorrectly assumed to be smaller than 2*sizeof(void*)");
static_assert(sizeof(Interconnect::Emitter::Signal(Emitter::*)(Args...)) <= sizeof(Implementation::SignalData),
"size of member function pointer is incorrectly assumed to be smaller");
static_assert(std::is_base_of<Emitter, EmitterObject>::value,
"Emitter object doesn't have given signal");

Expand Down Expand Up @@ -446,8 +446,8 @@ more information about connections.
@todo Connecting to signals
*/
template<class EmitterObject, class Emitter, class Receiver, class ReceiverObject, class ...Args> Connection connect(EmitterObject& emitter, Interconnect::Emitter::Signal(Emitter::*signal)(Args...), ReceiverObject& receiver, void(Receiver::*slot)(Args...)) {
static_assert(sizeof(Interconnect::Emitter::Signal(Emitter::*)(Args...)) <= 2*sizeof(void*),
"Size of member function pointer is incorrectly assumed to be smaller than 2*sizeof(void*)");
static_assert(sizeof(Interconnect::Emitter::Signal(Emitter::*)(Args...)) <= sizeof(Implementation::SignalData),
"Size of member function pointer is incorrectly assumed to be smaller");
static_assert(std::is_base_of<Emitter, EmitterObject>::value,
"Emitter object doesn't have given signal");
static_assert(std::is_base_of<Receiver, ReceiverObject>::value,
Expand Down

0 comments on commit b83c116

Please sign in to comment.