Packets: extended description of bad_cast exception in Packet.as()
[senf.git] / senf / Packets / Packet.cti
index 8e56512..8184317 100644 (file)
 #include <senf/Utils/Exception.hh>
 
 #define prefix_ inline
-///////////////////////////////cti.p///////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 
-///////////////////////////////////////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 // senf::Packet
 
 // conversion constructors
 
 template <class PacketType>
-prefix_ senf::Packet::Packet(ConcretePacket<PacketType> packet)
+prefix_ senf::Packet::Packet(ConcretePacket<PacketType> const & packet)
     : packet_(packet.ptr())
 {}
 
@@ -54,7 +54,7 @@ template <class OtherPacket>
 prefix_ bool senf::Packet::is()
     const
 {
-    return ptr()->is<typename OtherPacket::type>();
+    return valid() && ptr()->is<typename OtherPacket::type>();
 }
 
 template <class OtherPacket>
@@ -62,7 +62,18 @@ prefix_ OtherPacket senf::Packet::as()
     const
 {
     if (!is<OtherPacket>())
-        throw WrapException<std::bad_cast>(std::bad_cast());
+        throw WrapException<std::bad_cast>(std::bad_cast())
+            << ": called packet::as() with wrong PacketType: "
+            << (valid() ? typeId().prettyName() : "invalid packet")
+            << " != " << prettyName(typeid(OtherPacket));
+    return OtherPacket(ptr()->as<typename OtherPacket::type>());
+}
+
+template <class OtherPacket>
+prefix_ OtherPacket senf::Packet::as(NoThrow_t)
+    const
+{
+    SENF_ASSERT( is<OtherPacket>(), "Bad cast, called packet::as(nothrow) with wrong PacketType");
     return OtherPacket(ptr()->as<typename OtherPacket::type>());
 }
 
@@ -78,7 +89,8 @@ prefix_ OtherPacket senf::Packet::next(NoThrow_t)
     const
 {
     Packet p (next(nothrow));
-    return p && p.is<OtherPacket>() ? p.as<OtherPacket>() : OtherPacket();
+    return p && p.is<OtherPacket>() ?
+            OtherPacket(p.ptr()->as<typename OtherPacket::type>()) : OtherPacket();
 }
 
 template <class OtherPacket>
@@ -102,7 +114,8 @@ prefix_ OtherPacket senf::Packet::prev(NoThrow_t)
     const
 {
     Packet p (prev(nothrow));
-    return p && p.is<OtherPacket>() ? p.as<OtherPacket>() : OtherPacket();
+    return p && p.is<OtherPacket>() ?
+            OtherPacket(p.ptr()->as<typename OtherPacket::type>()) : OtherPacket();
 }
 
 template <class OtherPacket>
@@ -148,7 +161,7 @@ prefix_ Annotation const & senf::Packet::annotation()
     return ptr()->annotation<Annotation>();
 }
 
-///////////////////////////////////////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 // senf::ConcretePacket<PacketType>
 
 // structors and default members
@@ -232,7 +245,7 @@ senf::ConcretePacket<PacketType>::createAfter(Packet const & packet, size_type s
 
 template <class PacketType>
 prefix_ senf::ConcretePacket<PacketType>
-senf::ConcretePacket<PacketType>::createAfter(Packet const & packet, size_type size, 
+senf::ConcretePacket<PacketType>::createAfter(Packet const & packet, size_type size,
                                               senf::NoInit_t)
 {
     return ConcretePacket(interpreter::createAfter(packet.ptr(), size, senf::noinit));
@@ -267,6 +280,20 @@ senf::ConcretePacket<PacketType>::createBefore(Packet const & packet, senf::NoIn
     return ConcretePacket(interpreter::createBefore(packet.ptr(), senf::noinit));
 }
 
+template <class PacketType>
+prefix_ senf::ConcretePacket<PacketType>
+senf::ConcretePacket<PacketType>::createInsertBefore(Packet const & packet)
+{
+    return ConcretePacket(interpreter::createInsertBefore(packet.ptr()));
+}
+
+template <class PacketType>
+prefix_ senf::ConcretePacket<PacketType>
+senf::ConcretePacket<PacketType>::createInsertBefore(Packet const & packet, senf::NoInit_t)
+{
+    return ConcretePacket(interpreter::createInsertBefore(packet.ptr(), senf::noinit));
+}
+
 // Create a clone of the current packet
 
 template <class PacketType>
@@ -298,19 +325,18 @@ senf::ConcretePacket<PacketType>::operator->()
 // private members
 
 template <class PacketType>
-prefix_ senf::ConcretePacket<PacketType>::ConcretePacket(typename interpreter::ptr packet_)
+prefix_ senf::ConcretePacket<PacketType>::ConcretePacket(typename interpreter::ptr const & packet_)
     : Packet(packet_)
 {}
 
 template <class PacketType>
-prefix_ typename senf::ConcretePacket<PacketType>::interpreter::ptr
-senf::ConcretePacket<PacketType>::ptr()
+prefix_ typename senf::ConcretePacket<PacketType>::interpreter * senf::ConcretePacket<PacketType>::ptr()
     const
 {
-    return boost::static_pointer_cast< PacketInterpreter<PacketType> >(Packet::ptr());
+    return static_cast< PacketInterpreter<PacketType> *>( Packet::ptr().get());
 }
 
-///////////////////////////////cti.e///////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 #undef prefix_
 
 \f