/** \file
\brief PacketImpl public header */
-#ifndef HH_PacketImpl_
-#define HH_PacketImpl_ 1
+#ifndef HH_SENF_Packets_PacketImpl_
+#define HH_SENF_Packets_PacketImpl_ 1
// Custom includes
#include <memory>
+#include <vector>
#include <boost/utility.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/has_trivial_constructor.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/static_assert.hpp>
#include "../Utils/pool_alloc_mixin.hh"
#include "PacketTypes.hh"
+#include "../Utils/singleton.hh"
//#include "PacketImpl.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
+
+ /** \brief Marker base-class for complex annotations
+
+ This class is used as a base class to mark an annotation type as complex. A complex
+ annotation will have it's constructor/destructor called. Non-complex annotations will not
+ have their constructor called, they will be zero initialized. The destructor of non-complex
+ annotations is never called.
+
+ An annotation must be marked as complex if it is not <a
+ href="http://en.wikipedia.org/wiki/Plain_Old_Data_Structures">POD</a>. Simplified, an
+ annotation must be marked as ComplexAnnotation, if
+
+ \li it has a (user defined) constructor or destructor
+ \li it has any data members which have (user defined) constructors or destructors
+
+ \see \ref packet_usage_annotation
+ */
+ struct ComplexAnnotation {};
+
namespace detail {
+ struct AnnotationP
+ {
+ virtual ~AnnotationP();
+ };
+
+ template <class Annotation>
+ struct TAnnotationP
+ : public AnnotationP
+ {
+ Annotation annotation;
+ };
+
+ union AnnotationEntry {
+ AnnotationP * p;
+ unsigned long long i;
+ };
+
+ struct AnnotationIndexerBase
+ {
+ static unsigned maxAnnotations;
+ static std::vector<bool> & small();
+ };
+
+ template <class Annotation>
+ struct AnnotationIndexer
+ : public senf::singleton< AnnotationIndexer<Annotation> >,
+ public AnnotationIndexerBase
+ {
+ AnnotationIndexer();
+ unsigned index_;
+ static unsigned index();
+ static bool const Complex = boost::is_base_of<ComplexAnnotation, Annotation>::value;
+ static bool const Small = (sizeof(Annotation) <= sizeof(AnnotationEntry) && ! Complex);
+
+# ifdef BOOST_HAS_TYPE_TRAITS_INTRINSICS
+
+ BOOST_STATIC_ASSERT(( (boost::has_trivial_constructor<Annotation>::value
+ && boost::has_trivial_destructor<Annotation>::value)
+ || Complex ));
+
+# endif
+ };
+
+ template <class Annotation, bool Small = AnnotationIndexer<Annotation>::Small>
+ struct GetAnnotation
+ {
+ static Annotation & get(AnnotationEntry & e);
+ };
+
+ template <class Annotation>
+ struct GetAnnotation<Annotation, true>
+ {
+ static Annotation & get(AnnotationEntry & e);
+ };
+
/** \brief Internal: Packet data storage
\internal
void erase(PacketData * self, iterator first, iterator last);
void clear(PacketData * self);
+ void reserve(size_type n);
+ size_type capacity() const;
+
+ // Annotations
+ template <class Annotation>
+ Annotation & annotation();
+
/** \brief Internal: Keep PacketImpl instance alive
\internal
refcount_t refcount_;
raw_container data_;
interpreter_list interpreters_;
+
+ typedef std::vector<AnnotationEntry> Annotations;
+ Annotations annotations_;
void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
void updateIterators(PacketData * self, difference_type pos, difference_type n);
///////////////////////////////hh.e////////////////////////////////////////
#endif
-#if !defined(HH_Packets__decls_) && !defined(HH_PacketImpl_i_)
-#define HH_PacketImpl_i_
+#if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketImpl_i_)
+#define HH_SENF_Packets_PacketImpl_i_
#include "PacketImpl.cci"
//#include "PacketImpl.ct"
#include "PacketImpl.cti"