From 594e3fd75688596026cbb85c6a6bb3210ac8b7c1 Mon Sep 17 00:00:00 2001
From: sbund <sbund@wiback.org>
Date: Thu, 31 Aug 2006 14:59:19 +0000
Subject: [PATCH] static cast

---
 Socket/AddressingPolicy.hh            |   2 +-
 Socket/ClientSocketHandle.cti         |  10 +
 Socket/ClientSocketHandle.hh          |   2 +
 Socket/FileHandle.cci                 |   6 +
 Socket/FileHandle.hh                  |   2 +
 Socket/ProtocolClientSocketHandle.cti |  10 +-
 Socket/ProtocolClientSocketHandle.hh  |   2 +
 Socket/ProtocolServerSocketHandle.cti |  14 ++
 Socket/ProtocolServerSocketHandle.hh  |   3 +
 Socket/ServerSocketHandle.cti         |  16 ++
 Socket/ServerSocketHandle.hh          |   3 +
 Socket/SocketHandle.cti               |  24 ++-
 Socket/SocketHandle.hh                |   5 +-
 Socket/SocketHandle.test.cc           |   6 +-
 Socket/SocketPolicy.hh                | 123 +----------
 Socket/SocketPolicy.ih                | 298 ++++++++++----------------
 16 files changed, 218 insertions(+), 308 deletions(-)

diff --git a/Socket/AddressingPolicy.hh b/Socket/AddressingPolicy.hh
index f0024bc8d..d18e1db92 100644
--- a/Socket/AddressingPolicy.hh
+++ b/Socket/AddressingPolicy.hh
@@ -34,7 +34,7 @@ namespace lib {
 
     struct NoAddressingPolicy : public AddressingPolicyBase
     {
-        typedef satcom::lib::nil Address;
+        typedef void Address;
     };
 
 }}
diff --git a/Socket/ClientSocketHandle.cti b/Socket/ClientSocketHandle.cti
index f595645dc..757bb0e44 100644
--- a/Socket/ClientSocketHandle.cti
+++ b/Socket/ClientSocketHandle.cti
@@ -183,6 +183,16 @@ prefix_ void satcom::lib::ClientSocketHandle<Policy>::sndbuf(unsigned size)
     Policy::BufferingPolicy::sndbuf(*this,size);
 }
 
+///////////////////////////////////////////////////////////////////////////
+
+template <class Policy>
+prefix_ satcom::lib::ClientSocketHandle<Policy>
+satcom::lib::ClientSocketHandle<Policy>::cast_static(FileHandle handle)
+{
+    // TODO: Add BOOST_ASSERT
+    return ClientSocketHandle(handle, true);
+}
+
 ///////////////////////////////cti.e///////////////////////////////////////
 #undef prefix_
 
diff --git a/Socket/ClientSocketHandle.hh b/Socket/ClientSocketHandle.hh
index 1482a472a..1e0f199f9 100644
--- a/Socket/ClientSocketHandle.hh
+++ b/Socket/ClientSocketHandle.hh
@@ -119,6 +119,8 @@ namespace lib {
         void         sndbuf      (unsigned size);
         
         ///@}
+        
+        static ClientSocketHandle cast_static(FileHandle handle);
                  
     protected:
         ClientSocketHandle(FileHandle other, bool isChecked);
diff --git a/Socket/FileHandle.cci b/Socket/FileHandle.cci
index 301990fd6..63ca57b15 100644
--- a/Socket/FileHandle.cci
+++ b/Socket/FileHandle.cci
@@ -210,6 +210,12 @@ prefix_ void satcom::lib::FileHandle::fd(int fd)
     body().fd(fd);
 }
 
+prefix_ satcom::lib::FileHandle::FileHandle
+satcom::lib::FileHandle::cast_static(FileHandle handle)
+{
+    return handle;
+}
+
 ///////////////////////////////cci.e///////////////////////////////////////
 #undef prefix_
 
diff --git a/Socket/FileHandle.hh b/Socket/FileHandle.hh
index 9027c7c87..85b958249 100644
--- a/Socket/FileHandle.hh
+++ b/Socket/FileHandle.hh
@@ -74,6 +74,8 @@ namespace lib {
 
         int fd() const;
 
+        static FileHandle cast_static(FileHandle handle);
+
     protected:
         explicit FileHandle(std::auto_ptr<FileBody> body);
 
diff --git a/Socket/ProtocolClientSocketHandle.cti b/Socket/ProtocolClientSocketHandle.cti
index bd4041f4f..30a2d81bd 100644
--- a/Socket/ProtocolClientSocketHandle.cti
+++ b/Socket/ProtocolClientSocketHandle.cti
@@ -43,7 +43,7 @@ prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::ProtocolClientS
 template <class SocketProtocol>
 prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::
 ProtocolClientSocketHandle(FileHandle other, bool isChecked)
-    : ClientSocketHandle<typename Protocol::Policy>(other, true)
+    : ClientSocketHandle<typename Protocol::Policy>(other, isChecked)
 {}
 
 template <class SocketProtocol>
@@ -54,6 +54,14 @@ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::protocol()
     return static_cast<SocketProtocol const &>(this->body().protocol());
 }
 
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>
+satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::cast_static(FileHandle handle)
+{
+    // TODO: Add BOOST_ASSERT
+    return ProtocolClientSocketHandle(handle,true);
+}
+
 ///////////////////////////////cti.e///////////////////////////////////////
 #undef prefix_
 
diff --git a/Socket/ProtocolClientSocketHandle.hh b/Socket/ProtocolClientSocketHandle.hh
index fb06a4aab..e9a7160d8 100644
--- a/Socket/ProtocolClientSocketHandle.hh
+++ b/Socket/ProtocolClientSocketHandle.hh
@@ -60,6 +60,8 @@ namespace lib {
 
         Protocol const & protocol();
 
+        static ProtocolClientSocketHandle cast_static(FileHandle handle);
+
     protected:
         ProtocolClientSocketHandle(FileHandle other, bool isChecked);
 
diff --git a/Socket/ProtocolServerSocketHandle.cti b/Socket/ProtocolServerSocketHandle.cti
index 01087c5b6..bf1387032 100644
--- a/Socket/ProtocolServerSocketHandle.cti
+++ b/Socket/ProtocolServerSocketHandle.cti
@@ -55,6 +55,20 @@ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::accept()
         FileHandle(this->ServerSocketHandle<typename SocketProtocol::Policy>::accept()),true);
 }
 
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>
+satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::cast_static(FileHandle handle)
+{
+    // TODO: Add BOOST_ASSERT
+    return ProtocolServerSocketHandle(handle,true);
+}
+
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::
+ProtocolServerSocketHandle(FileHandle other, bool isChecked)
+    : ServerSocketHandle<typename SocketProtocol::Policy>(other,isChecked)
+{}
+
 ///////////////////////////////cti.e///////////////////////////////////////
 #undef prefix_
 
diff --git a/Socket/ProtocolServerSocketHandle.hh b/Socket/ProtocolServerSocketHandle.hh
index 3638199c7..d02a18d65 100644
--- a/Socket/ProtocolServerSocketHandle.hh
+++ b/Socket/ProtocolServerSocketHandle.hh
@@ -62,7 +62,10 @@ namespace lib {
 
         ProtocolClientSocketHandle<SocketProtocol> accept();
 
+        static ProtocolServerSocketHandle cast_static(FileHandle handle);
+
     protected:
+        ProtocolServerSocketHandle(FileHandle other, bool isChecked);
 
     private:
 
diff --git a/Socket/ServerSocketHandle.cti b/Socket/ServerSocketHandle.cti
index b4cdcd84c..c4018343d 100644
--- a/Socket/ServerSocketHandle.cti
+++ b/Socket/ServerSocketHandle.cti
@@ -103,6 +103,22 @@ satcom::lib::ServerSocketHandle<Policy>::acceptfrom(Address & addr)
                               Policy::CommunicationPolicy::accept(*this,addr));
 }
 
+///////////////////////////////////////////////////////////////////////////
+
+template <class Policy>
+prefix_ satcom::lib::ServerSocketHandle<Policy>::ServerSocketHandle(FileHandle other,
+                                                                    bool isChecked)
+    : SocketHandle<Policy>(other, isChecked)
+{}
+
+template <class Policy>
+prefix_ satcom::lib::ServerSocketHandle<Policy>
+satcom::lib::ServerSocketHandle<Policy>::cast_static(FileHandle handle)
+{
+    // TODO: Add BOOST_ASSERT
+    return ServerSocketHandle(handle,true);
+}
+
 ///////////////////////////////cti.e///////////////////////////////////////
 #undef prefix_
 
diff --git a/Socket/ServerSocketHandle.hh b/Socket/ServerSocketHandle.hh
index 2f9b944d0..22425cd3a 100644
--- a/Socket/ServerSocketHandle.hh
+++ b/Socket/ServerSocketHandle.hh
@@ -91,7 +91,10 @@ namespace lib {
         
         ///@}
 
+        static ServerSocketHandle cast_static(FileHandle handle);
+
     protected:
+        ServerSocketHandle(FileHandle other, bool isChecked);
         explicit ServerSocketHandle(std::auto_ptr<SocketProtocol> protocol);
 
     private:
diff --git a/Socket/SocketHandle.cti b/Socket/SocketHandle.cti
index 1f9d8536f..8a4857865 100644
--- a/Socket/SocketHandle.cti
+++ b/Socket/SocketHandle.cti
@@ -54,7 +54,10 @@ satcom::lib::SocketHandle<SocketPolicy>::SocketHandle(std::auto_ptr<SocketProtoc
 template <class SocketPolicy>
 prefix_ satcom::lib::SocketHandle<SocketPolicy>::SocketHandle(FileHandle other, bool isChecked)
     : FileHandle(other)
-{}
+{
+    BOOST_ASSERT( isChecked );
+    BOOST_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()) );
+}
 
 template <class SocketPolicy>
 prefix_ satcom::lib::SocketBody & satcom::lib::SocketHandle<SocketPolicy>::body()
@@ -84,6 +87,25 @@ prefix_ void satcom::lib::SocketHandle<SocketPolicy>::assign(FileHandle other)
     FileHandle::operator=(other);
 }
 
+template <class SocketPolicy>
+prefix_ satcom::lib::SocketHandle<SocketPolicy>
+satcom::lib::SocketHandle<SocketPolicy>::cast_static(FileHandle handle)
+{
+    // TODO: Add BOOST_ASSERT
+    return SocketHandle(handle,true);
+}
+
+template <class Target, class Source>
+prefix_ Target satcom::lib::static_socket_cast(Source handle)
+{
+    BOOST_STATIC_ASSERT((
+        boost::is_convertible<Source*,FileHandle*>::value &&
+        boost::is_convertible<Target*,FileHandle*>::value &&
+        ( boost::is_convertible<Source,Target>::value ||
+          boost::is_convertible<Target,Source>::value ) ));
+    return Target::cast_static(handle);
+}
+
 ///////////////////////////////cti.e///////////////////////////////////////
 #undef prefix_
 
diff --git a/Socket/SocketHandle.hh b/Socket/SocketHandle.hh
index 8dcb570f4..153e58e25 100644
--- a/Socket/SocketHandle.hh
+++ b/Socket/SocketHandle.hh
@@ -72,6 +72,8 @@ namespace lib {
         template <class OtherPolicy>
         typename IsCompatible<OtherPolicy>::type const & operator=(SocketHandle<OtherPolicy> other);
 
+        static SocketHandle cast_static(FileHandle handle);
+
     protected:
         explicit SocketHandle(std::auto_ptr<SocketProtocol> protocol);
         SocketHandle(FileHandle other, bool isChecked);
@@ -86,7 +88,8 @@ namespace lib {
 
     };
 
-
+    template <class Target, class Source>
+    Target static_socket_cast(Source handle);
 }}
 
 ///////////////////////////////hh.e////////////////////////////////////////
diff --git a/Socket/SocketHandle.test.cc b/Socket/SocketHandle.test.cc
index 0f25c3246..4f7c90c67 100644
--- a/Socket/SocketHandle.test.cc
+++ b/Socket/SocketHandle.test.cc
@@ -57,8 +57,10 @@ BOOST_AUTO_UNIT_TEST(socketHandle)
     typedef sl::SocketHandle<OtherSocketPolicy> OtherSocketHandle;
     
     MySocketHandle myh;
-    OtherSocketHandle ssh (myh);
-    ssh = myh;
+    OtherSocketHandle osh (myh);
+    osh = myh;
+    typedef sl::SocketHandle<sl::test::SomeProtocol::Policy> SomeSocketHandle;
+    SomeSocketHandle ssh = satcom::lib::static_socket_cast<SomeSocketHandle>(osh);
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
diff --git a/Socket/SocketPolicy.hh b/Socket/SocketPolicy.hh
index 9200c8ea8..74de6f3c0 100644
--- a/Socket/SocketPolicy.hh
+++ b/Socket/SocketPolicy.hh
@@ -24,7 +24,6 @@
 #define HH_SocketPolicy_ 1
 
 // Custom includes
-#include <boost/type_traits.hpp>
 
 //#include "SocketPolicy.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -32,122 +31,14 @@
 namespace satcom {
 namespace lib {
 
-    class AddressingPolicyBase
-    {};
-    typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
+#   define SATCOM_LIB_SocketPolicy_Policies \
+	(AddressingPolicy)                      \
+        (FramingPolicy)                         \
+	(CommunicationPolicy)                   \
+	(ReadPolicy)                            \
+	(WritePolicy)                           \
+	(BufferingPolicy)
 
-    class FramingPolicyBase
-    {};
-    typedef FramingPolicyBase UnspecifiedFramingPolicy;
-    
-    class CommunicationPolicyBase
-    {};
-    typedef CommunicationPolicyBase UnspecifiedCommunicationPolicy;
-    
-    class ReadPolicyBase
-    {};
-    typedef ReadPolicyBase UnspecifiedReadPolicy;
-    
-    class WritePolicyBase
-    {};
-    typedef WritePolicyBase UnspecifiedWritePolicy;
-    
-    class BufferingPolicyBase
-    {};
-    typedef BufferingPolicyBase UnspecifiedBufferingPolicy;
-    
-    class SocketPolicyBase
-    {
-        typedef AddressingPolicyBase AddressingPolicy;
-        typedef FramingPolicyBase FramingPolicy;
-        typedef CommunicationPolicyBase CommunicationPolicy;
-        typedef ReadPolicyBase ReadPolicy;
-        typedef WritePolicyBase WritePolicy;
-        typedef BufferingPolicyBase BufferingPolicy;
-    };
-
-    template <class AddressingPolicy_=AddressingPolicyBase,
-              class FramingPolicy_=FramingPolicyBase,
-              class CommunicationPolicy_=CommunicationPolicyBase,
-              class ReadPolicy_=ReadPolicyBase,
-              class WritePolicy_=WritePolicyBase,
-              class BufferingPolicy_=BufferingPolicyBase>
-    class SocketPolicy
-        : public SocketPolicyBase
-    {
-    public:
-        typedef AddressingPolicy_ AddressingPolicy;
-        typedef FramingPolicy_ FramingPolicy;
-        typedef CommunicationPolicy_ CommunicationPolicy;
-        typedef ReadPolicy_ ReadPolicy;
-        typedef WritePolicy_ WritePolicy;
-        typedef BufferingPolicy_ BufferingPolicy;
-
-        AddressingPolicy addressingPolicy;
-        FramingPolicy framingPolicy;
-        CommunicationPolicy communicationPolicy;
-        ReadPolicy readPolicy;
-        WritePolicy writePolicy;
-        BufferingPolicy bufferingPolicy;
-    };
-
-    struct nil {};
-
-    template <class T1, class T2=nil, class T3=nil, class T4=nil, class T5=nil, class T6=nil>
-    class MakeSocketPolicy;
-    // the rest is implementation detail
-
-    template <class BasePolicy, class DerivedPolicy>
-    struct SocketPolicyIsBaseOf;
-    // the rest is implementation detail ...
-
-    template <class Policy, class Trait>
-    struct AddressingPolicyIs;
-    template <class Policy, class Trait>
-    struct IfAddressingPolicyIs;
-    template <class Policy, class Trait>
-    struct IfAddressingPolicyIsNot;
-    // the rest is implementation detail ...
-
-    template <class Policy, class Trait>
-    struct FramingPolicyIs;
-    template <class Policy, class Trait>
-    struct IfFramingPolicyIs;
-    template <class Policy, class Trait>
-    struct IfFramingPolicyIsNot;
-    // the rest is implementation detail ...
-
-    template <class Policy, class Trait>
-    struct CommunicationPolicyIs;
-    template <class Policy, class Trait>
-    struct IfCommunicationPolicyIs;
-    template <class Policy, class Trait>
-    struct IfCommunicationPolicyIsNot;
-    // the rest is implementation detail ...
-
-    template <class Policy, class Trait>
-    struct ReadPolicyIs;
-    template <class Policy, class Trait>
-    struct IfReadPolicyIs;
-    template <class Policy, class Trait>
-    struct IfReadPolicyIsNot;
-    // the rest is implementation detail ...
-
-    template <class Policy, class Trait>
-    struct WritePolicyIs;
-    template <class Policy, class Trait>
-    struct IfWritePolicyIs;
-    template <class Policy, class Trait>
-    struct IfWritePolicyIsNot;
-    // the rest is implementation detail ...
-
-    template <class Policy, class Trait>
-    struct BufferingPolicyIs;
-    template <class Policy, class Trait>
-    struct IfBufferingPolicyIs;
-    template <class Policy, class Trait>
-    struct IfBufferingPolicyIsNot;
-    // the rest is implementation detail ...
 }}
 
 //////////////////////////////hh.e////////////////////////////////////////
diff --git a/Socket/SocketPolicy.ih b/Socket/SocketPolicy.ih
index d88a0e3e1..e3c2696a9 100644
--- a/Socket/SocketPolicy.ih
+++ b/Socket/SocketPolicy.ih
@@ -24,6 +24,21 @@
 #define IH_SocketPolicy_ 1
 
 // Custom includes
+#include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/seq/for_each_i.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+#include <boost/preprocessor/arithmetic/dec.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/control/if.hpp>
+#include <boost/preprocessor/comparison/equal.hpp>
+
+#include <boost/type_traits.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/mpl/fold.hpp>
 #include <boost/mpl/if.hpp>
@@ -34,97 +49,76 @@
 
 namespace satcom {
 namespace lib {
-namespace impl{
 
-    template <int N>
-    struct SocketPolicy_rv
-    {
-        int v[N];
-    };
-    
-    SocketPolicy_rv<1> MakeSocketPolicy_merge_(AddressingPolicyBase*);
-    SocketPolicy_rv<2> MakeSocketPolicy_merge_(FramingPolicyBase*);
-    SocketPolicy_rv<3> MakeSocketPolicy_merge_(CommunicationPolicyBase*);
-    SocketPolicy_rv<4> MakeSocketPolicy_merge_(ReadPolicyBase*);
-    SocketPolicy_rv<5> MakeSocketPolicy_merge_(WritePolicyBase*);
-    SocketPolicy_rv<6> MakeSocketPolicy_merge_(BufferingPolicyBase*);
+#   define SP_DeclareBase(x1,x2,SomePolicy) \
+        struct BOOST_PP_CAT(SomePolicy,Base)                                            \
+        { virtual ~ BOOST_PP_CAT(SomePolicy,Base) () {} };                              \
+        typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy);
 
-    template <class Base, class Policy, int N>
-    struct MakeSocketPolicy_merge
-    {};
+    BOOST_PP_SEQ_FOR_EACH( SP_DeclareBase, nix, SATCOM_LIB_SocketPolicy_Policies )
 
-    template <class Base, class Policy>
-    struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<1>)>
+#   undef SP_DeclareBase
+        
+    struct SocketPolicyBase
     {
-        typedef SocketPolicy< 
-            Policy,
-            typename Base::FramingPolicy,
-            typename Base::CommunicationPolicy,
-            typename Base::ReadPolicy,
-            typename Base::WritePolicy,
-            typename Base::BufferingPolicy> type;
-    };
+#       define SP_DeclareTypedef(x1,x2,SomePolicy) \
+            typedef BOOST_PP_CAT(SomePolicy,Base) SomePolicy;
 
-    template <class Base, class Policy>
-    struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<2>)>
-    {
-        typedef SocketPolicy< 
-            typename Base::AddressingPolicy,
-            Policy,
-            typename Base::CommunicationPolicy,
-            typename Base::ReadPolicy,
-            typename Base::WritePolicy,
-            typename Base::BufferingPolicy> type;
-    };
+        BOOST_PP_SEQ_FOR_EACH( SP_DeclareTypedef, nix, SATCOM_LIB_SocketPolicy_Policies )
 
-    template <class Base, class Policy>
-    struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<3>)>
-    {
-        typedef SocketPolicy< 
-            typename Base::AddressingPolicy,
-            typename Base::FramingPolicy,
-            Policy,
-            typename Base::ReadPolicy,
-            typename Base::WritePolicy,
-            typename Base::BufferingPolicy> type;
+#       undef SP_DeclareTypedef
     };
 
-    template <class Base, class Policy>
-    struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<4>)>
-    {
-        typedef SocketPolicy< 
-            typename Base::AddressingPolicy,
-            typename Base::FramingPolicy,
-            typename Base::CommunicationPolicy,
-            Policy,
-            typename Base::WritePolicy,
-            typename Base::BufferingPolicy> type;
-    };
+#   define SP_TemplateArgs(x1,x2,n,SomePolicy) \
+        BOOST_PP_COMMA_IF( n ) \
+        class BOOST_PP_CAT(SomePolicy,_) = BOOST_PP_CAT(SomePolicy,Base)
 
-    template <class Base, class Policy>
-    struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<5>)>
+    template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, nix, SATCOM_LIB_SocketPolicy_Policies ) >
+    struct SocketPolicy
+        : public SocketPolicyBase
     {
-        typedef SocketPolicy< 
-            typename Base::AddressingPolicy,
-            typename Base::FramingPolicy,
-            typename Base::CommunicationPolicy,
-            typename Base::ReadPolicy,
-            Policy,
-            typename Base::BufferingPolicy> type;
-    };
+#   define SP_DeclarePolicyMember(x1,x2,SomePolicy) \
+        typedef BOOST_PP_CAT(SomePolicy,_) SomePolicy; \
+        SomePolicy BOOST_PP_CAT(the,SomePolicy);
 
-    template <class Base, class Policy>
-    struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<6>)>
-    {
-        typedef SocketPolicy< 
-            typename Base::AddressingPolicy,
-            typename Base::FramingPolicy,
-            typename Base::CommunicationPolicy,
-            typename Base::ReadPolicy,
-            typename Base::WritePolicy,
-            Policy> type;
+        BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SATCOM_LIB_SocketPolicy_Policies )
+#   undef SP_DeclarePolicyMember
     };
 
+#   undef SP_TemplateArgs
+
+namespace impl {
+
+    struct nil {};
+
+    template <int N>
+    struct SocketPolicy_rv
+    { int v[N+1]; };
+    
+    template <class Base, class Policy, int N>
+    struct MakeSocketPolicy_merge
+    {};
+
+#   define SP_DeclareMakeSocketPolicy_merge_member(r,n,m,SomePolicy) \
+        BOOST_PP_COMMA_IF( m ) \
+        BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy )
+
+#    define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( BOOST_PP_SEQ_SIZE( SATCOM_LIB_SocketPolicy_Policies ) ) )
+#    define BOOST_PP_LOCAL_MACRO(n) \
+        SocketPolicy_rv<n> MakeSocketPolicy_merge_(BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SATCOM_LIB_SocketPolicy_Policies ),Base)*);      \
+                                                                                                                                        \
+        template <class Base, class Policy>                                                                                             \
+        struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<n>)>                                                           \
+        {                                                                                                                               \
+            typedef SocketPolicy<                                                                                                       \
+               BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, n, SATCOM_LIB_SocketPolicy_Policies )                  \
+               > type;                                                                                                                  \
+        };
+
+#   include BOOST_PP_LOCAL_ITERATE()
+
+#   undef SP_DeclareMakeSocketPolicy_merge_member
+
     struct MakeSocketPolicy_fold
     {
         template <class Base, class Policy>
@@ -147,16 +141,19 @@ namespace impl{
         typedef typename boost::mpl::fold< Vector, Base, MakeSocketPolicy_fold >::type policy;
     };
 
+#   define SP_DeclareArguments(x1,x2,n,SomePolicy) \
+    	BOOST_PP_COMMA_IF( n )   \
+	typename Base::SomePolicy *
+
     template <class Base>
-    SocketPolicy_rv<1> SocketPolicy_checkcompat_(typename Base::AddressingPolicy*,
-                                                 typename Base::FramingPolicy*,
-                                                 typename Base::CommunicationPolicy*,
-                                                 typename Base::ReadPolicy*,
-                                                 typename Base::WritePolicy*,
-                                                 typename Base::BufferingPolicy*);
+    SocketPolicy_rv<1> SocketPolicy_checkcompat_(
+        BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, nix, SATCOM_LIB_SocketPolicy_Policies ) );
+
+#   undef SP_DeclareArguments
 
     template <class Base>
-    SocketPolicy_rv<2> SocketPolicy_checkcompat_(void*, void*, void*, void*, void*, void*);
+    SocketPolicy_rv<2> SocketPolicy_checkcompat_( 
+        BOOST_PP_ENUM_PARAMS( BOOST_PP_SEQ_SIZE(SATCOM_LIB_SocketPolicy_Policies), void * BOOST_PP_INTERCEPT ) );
 
     template <int Size>
     struct SocketPolicy_checkcompat
@@ -168,28 +165,26 @@ namespace impl{
         : public boost::true_type
     {};
 
+
+#   define SP_DeclareArguments(x1,x2,n,SomePolicy) \
+        BOOST_PP_COMMA_IF( n ) \
+        static_cast<typename Derived::SomePolicy *>(0)
+
     template <class Base, class Derived>
     struct SocketPolicy_compatibility
-        : public SocketPolicy_checkcompat< sizeof(SocketPolicy_checkcompat_<Base>(
-                                                      static_cast<typename Derived::AddressingPolicy*>(0),
-                                                      static_cast<typename Derived::FramingPolicy*>(0),
-                                                      static_cast<typename Derived::CommunicationPolicy*>(0),
-                                                      static_cast<typename Derived::ReadPolicy*>(0),
-                                                      static_cast<typename Derived::WritePolicy*>(0),
-                                                      static_cast<typename Derived::BufferingPolicy*>(0))) >
+        : public SocketPolicy_checkcompat< sizeof(
+            SocketPolicy_checkcompat_<Base>(
+                BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, nix, SATCOM_LIB_SocketPolicy_Policies ) )) >
     {};
 
-}}}
-
-namespace satcom {
-namespace lib {
+} // namespace impl
 
-    template <class T1, class T2, class T3, class T4, class T5, class T6>
+    template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( BOOST_PP_SEQ_SIZE( SATCOM_LIB_SocketPolicy_Policies ), class T, satcom::lib::impl::nil ) >
     class MakeSocketPolicy
-        : public boost::mpl::if_< boost::is_convertible< T1*, SocketPolicyBase* >,
-                                  impl::MakeSocketPolicy_impl< T1, boost::mpl::vector<T2,T3,T4,T5,T6> >,
+        : public boost::mpl::if_< boost::is_convertible< T0*, SocketPolicyBase* >,
+                                  impl::MakeSocketPolicy_impl< T0, boost::mpl::vector< BOOST_PP_ENUM_SHIFTED_PARAMS( BOOST_PP_SEQ_SIZE( SATCOM_LIB_SocketPolicy_Policies ), T ) > >,
                                   impl::MakeSocketPolicy_impl< SocketPolicy<>,
-                                                               boost::mpl::vector<T1,T2,T3,T4,T5,T6> > >::type
+                                                               boost::mpl::vector< BOOST_PP_ENUM_PARAMS( BOOST_PP_SEQ_SIZE( SATCOM_LIB_SocketPolicy_Policies ), T ) > > >::type
     {};
 
     template <class BasePolicy, class DerivedPolicy>
@@ -200,95 +195,26 @@ namespace lib {
                                   boost::false_type >::type
     {};
 
-    template <class Policy, class Trait>
-    struct AddressingPolicyIs
-        : public boost::is_convertible< typename Policy::AddressingPolicy*, Trait* >
-    {};
-
-    template <class Policy, class Trait>
-    struct IfAddressingPolicyIs
-        : public boost::enable_if< AddressingPolicyIs<Policy,Trait> >
-    {};
-
-    template <class Policy, class Trait>
-    struct IfAddressingPolicyIsNot
-        : public boost::enable_if_c< ! AddressingPolicyIs<Policy,Trait>::value >
-    {};
-
-    template <class Policy, class Trait>
-    struct FramingPolicyIs
-        : public boost::is_convertible< typename Policy::FramingPolicy*, Trait* >
-    {};
-
-    template <class Policy, class Trait>
-    struct IfFramingPolicyIs
-        : public boost::enable_if< FramingPolicyIs<Policy,Trait> >
-    {};
-
-    template <class Policy, class Trait>
-    struct IfFramingPolicyIsNot
-        : public boost::enable_if_c< ! FramingPolicyIs<Policy,Trait>::value >
-    {};
-
-    template <class Policy, class Trait>
-    struct CommunicationPolicyIs
-        : public boost::is_convertible< typename Policy::CommunicationPolicy*, Trait* >
-    {};
-
-    template <class Policy, class Trait>
-    struct IfCommunicationPolicyIs
-        : public boost::enable_if< CommunicationPolicyIs<Policy,Trait> >
-    {};
-
-    template <class Policy, class Trait>
-    struct IfCommunicationPolicyIsNot
-        : public boost::enable_if_c< ! CommunicationPolicyIs<Policy,Trait>::value >
-    {};
-
-    template <class Policy, class Trait>
-    struct ReadPolicyIs
-        : public boost::is_convertible< typename Policy::ReadPolicy*, Trait* >
-    {};
-
-    template <class Policy, class Trait>
-    struct IfReadPolicyIs
-        : public boost::enable_if< ReadPolicyIs<Policy,Trait> >
-    {};
-
-    template <class Policy, class Trait>
-    struct IfReadPolicyIsNot
-        : public boost::enable_if_c< ! ReadPolicyIs<Policy,Trait>::value >
-    {};
-
-    template <class Policy, class Trait>
-    struct WritePolicyIs
-        : public boost::is_convertible< typename Policy::WritePolicy*, Trait* >
-    {};
-
-    template <class Policy, class Trait>
-    struct IfWritePolicyIs
-        : public boost::enable_if< WritePolicyIs<Policy,Trait> >
-    {};
-
-    template <class Policy, class Trait>
-    struct IfWritePolicyIsNot
-        : public boost::enable_if_c< ! WritePolicyIs<Policy,Trait>::value >
-    {};
+#   define SP_DefineConditions(x1,x2,SomePolicy) \
+        template <class Policy, class Trait>                                                    \
+        struct BOOST_PP_CAT(SomePolicy,Is)                                                      \
+            : public boost::is_convertible< typename Policy::SomePolicy*, Trait* >              \
+        {};                                                                                     \
+                                                                                                \
+        template <class Policy, class Trait>                                                    \
+        struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),Is)                                     \
+            : public boost::enable_if< BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait> >              \
+        {};                                                                                     \
+                                                                                                \
+        template <class Policy, class Trait>                                                    \
+        struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),IsNot)                                  \
+            : public boost::enable_if_c< ! BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait>::value >   \
+        {};
 
-    template <class Policy, class Trait>
-    struct BufferingPolicyIs
-        : public boost::is_convertible< typename Policy::BufferingPolicy*, Trait* >
-    {};
+    BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, nix, SATCOM_LIB_SocketPolicy_Policies )
 
-    template <class Policy, class Trait>
-    struct IfBufferingPolicyIs
-        : public boost::enable_if< BufferingPolicyIs<Policy,Trait> >
-    {};
+#   undef SP_DefineConditions
 
-    template <class Policy, class Trait>
-    struct IfBufferingPolicyIsNot
-        : public boost::enable_if_c< ! BufferingPolicyIs<Policy,Trait>::value >
-    {};
 }}
 
 ///////////////////////////////ih.e////////////////////////////////////////
-- 
GitLab