diff --git a/autowiring/AutoPacket.h b/autowiring/AutoPacket.h index 3ad428181..94ceeaf13 100644 --- a/autowiring/AutoPacket.h +++ b/autowiring/AutoPacket.h @@ -7,6 +7,8 @@ #include "is_shared_ptr.h" #include "ObjectPool.h" #include "is_any.h" +#include +#include #include MEMORY_HEADER #include TYPE_INDEX_HEADER #include STL_UNORDERED_MAP @@ -167,8 +169,12 @@ class AutoPacket: template const T& Get(void) const { const T* retVal; - if(!Get(retVal)) - throw_rethrowable autowiring_error("Attempted to obtain a value which was not decorated on this packet"); + if(!Get(retVal)) { + std::stringstream ss; + ss << "Attempted to obtain a type " << typeid(retVal).name() + << " which was not decorated on this packet"; + throw std::runtime_error(ss.str()); + } return *retVal; } @@ -243,12 +249,16 @@ class AutoPacket: auto& entry = m_decorations[typeid(type)]; if (entry.satisfied) { std::stringstream ss; - ss << "Cannot decorate this packet with type " << typeid(type).name() + ss << "Cannot decorate this packet with type " << typeid(*ptr).name() << ", the requested decoration already exists"; throw std::runtime_error(ss.str()); } - if(entry.isCheckedOut) - throw std::runtime_error("Cannot check out this decoration, it's already checked out elsewhere"); + if(entry.isCheckedOut) { + std::stringstream ss; + ss << "Cannot check out decoration of type " << typeid(*ptr).name() + << ", it is already checked out elsewhere"; + throw std::runtime_error(ss.str()); + } entry.isCheckedOut = true; entry.wasCheckedOut = true; } @@ -353,8 +363,12 @@ class AutoPacket: std::lock_guard lk(m_lock); for(size_t i = 0; i < sizeof...(Ts); i++) { pTypeSubs[i] = &m_decorations[*sc_typeInfo[i]]; - if(pTypeSubs[i]->wasCheckedOut) - throw std::runtime_error("Cannot perform immediate decoration with type T, the requested decoration already exists"); + if(pTypeSubs[i]->wasCheckedOut) { + std::stringstream ss; + ss << "Cannot perform immediate decoration with type " << sc_typeInfo[i]->name() + << ", the requested decoration already exists"; + throw std::runtime_error(ss.str()); + } // Mark the entry as appropriate: pTypeSubs[i]->satisfied = true; diff --git a/src/autowiring/test/AutoFilterTest.cpp b/src/autowiring/test/AutoFilterTest.cpp index 6eaff96d8..8b2e72673 100644 --- a/src/autowiring/test/AutoFilterTest.cpp +++ b/src/autowiring/test/AutoFilterTest.cpp @@ -158,6 +158,24 @@ TEST_F(AutoFilterTest, VerifyNoMultiDecorate) { // Now finish saturating the filter and ensure we get a call: packet->Decorate(Decoration<1>()); EXPECT_LT(0, filterA->m_called) << "Filter was not called after being fully satisfied"; + + // Verify that DecorateImmedaite also yields an exception + Decoration<0> localDeco0; + EXPECT_ANY_THROW(packet->DecorateImmediate(localDeco0)) << "Redundant immediate decoration did not throw an exception as expected"; + + //NOTE: A typedef will throw an exception + typedef Decoration<0> isDeco0type; + EXPECT_ANY_THROW(packet->DecorateImmediate(isDeco0type())) << "Typedef failed to throw exception"; + + //NOTE: Inheritance will not throw an exception + class ofDeco0alias: public Decoration<0> {}; + try { + packet->Decorate(ofDeco0alias()); + } catch (...) { + FAIL() << "Class with inheritance reinterpreted as child type"; + } + + EXPECT_ANY_THROW(packet->DecorateImmediate(Decoration<2>(), Decoration<2>())) << "Repeated type in immediate decoration was not identified as an error"; } TEST_F(AutoFilterTest, VerifyNoNullCheckout) {