G
goodmen
I think the boost::concept_check is too complex.
Here is my solution about static interface and concept.
The static interface can be used as function param. It
is just a proxy of the real implementation.
And the Concept can be used when building the class
hierarchy. It is almost a private inherit, but for the sake of
providing an uniform look with the static interface version,
the private member is used.
In my opinion, the two versions of interface can be optimized
by the compiler and introduce no run-time burden.
My code need test and re-view.
Can anyone give me some advice?
Can anyone tell me whether there is a more graceful solution?
Any suggestion is welcome.
////////////////////////////////////////////////////////////////////
// Here is my code.
namespace common_utils_
{
template< typename T_Impl, bool T_UseRef >
struct si_root ;
template< typename T_Impl > struct si_root< T_Impl, true >
{
typedef T_Impl impl_t ;
si_root( void )
: m_pimpl( NULL )
{
}
void set_impl( impl_t* p )
{
m_pimpl = p ;
}
protected:
impl_t& impl( void )
{
assert( m_pimpl ) ;
return *m_pimpl ;
}
private:
impl_t* m_pimpl ;
} ;
template< typename T_Impl > struct si_root< T_Impl, false >
{
typedef T_Impl impl_t ;
protected:
impl_t& impl( void )
{
return m_impl ;
}
private:
impl_t m_impl ;
} ;
//
#define STATIC_INTERFACE_1(impl,T0) \
T0< si_root<impl,true> >
#define STATIC_INTERFACE_2(impl,T0,T1) \
T0< STATIC_INTERFACE_1(impl,T1) >
#define STATIC_INTERFACE_3(impl,T0,T1,T2) \
T0< STATIC_INTERFACE_2(impl,T1,T2) >
#define STATIC_INTERFACE_4(impl,T0,T1,T2,T3) \
T0< STATIC_INTERFACE_3(impl,T1,T2,T3) >
#define STATIC_CONCEPT_1(impl,T0) \
T0< si_root<impl,false> >
#define STATIC_CONCEPT_2(impl,T0,T1) \
T0< STATIC_CONCEPT_1(impl,T1) >
#define STATIC_CONCEPT_3(impl,T0,T1,T2) \
T0< STATIC_CONCEPT_2(impl,T1,T2) >
#define STATIC_CONCEPT_4(impl,T0,T1,T2,T3) \
T0< STATIC_CONCEPT_3(impl,T1,T2,T3) >
// exampls
namespace
{
template< typename T_Base > struct si_0 : public T_Base
{
typedef typename T_Base::impl_t::type_0 type_0 ;
void function0( void )
{
T_Base::impl().function0() ;
}
} ;
template< typename T_Base > struct si_1 : public T_Base
{
typedef typename T_Base::impl_t::type_1 type_1 ;
void function1( void )
{
T_Base::impl().function1() ;
}
} ;
template< typename T_Base > struct si_2 : public T_Base
{
typedef typename T_Base::impl_t::type_2 type_2 ;
void function2( void )
{
T_Base::impl().function2() ;
}
} ;
template< typename T_Base > struct si_3 : public T_Base
{
typedef typename T_Base::impl_t::type_3 type_3 ;
void function3( void )
{
T_Base::impl().function3() ;
}
} ;
struct TTTT
{
typedef int type_0 ;
typedef long type_1 ;
typedef float type_2 ;
typedef double type_3 ;
void function0( void )
{
std::cout << __LINE__ << ": " << __FUNCTION__ << " Is called."
<< std::endl ;
}
void function1( void )
{
std::cout << __LINE__ << ": " << __FUNCTION__ << " Is called."
<< std::endl ;
}
void function2( void )
{
std::cout << __LINE__ << ": " << __FUNCTION__ << " Is called."
<< std::endl ;
}
void function3( void )
{
std::cout << __LINE__ << ": " << __FUNCTION__ << " Is called."
<< std::endl ;
}
} ;
typedef STATIC_INTERFACE_4( TTTT, si_0, si_1, si_2, si_3 )
my_interface_t ;
typedef STATIC_CONCEPT_4( TTTT, si_0, si_1, si_2, si_3 )
my_concept_t ;
void interface_test( void )
{
TTTT obj ;
my_interface_t i ;
my_concept_t c ;
i.set_impl( &obj ) ;
i.function0() ;
i.function1() ;
i.function2() ;
i.function3() ;
c.function0() ;
c.function1() ;
c.function2() ;
c.function3() ;
}
} // anonymous
} // namespace common_utils_
Here is my solution about static interface and concept.
The static interface can be used as function param. It
is just a proxy of the real implementation.
And the Concept can be used when building the class
hierarchy. It is almost a private inherit, but for the sake of
providing an uniform look with the static interface version,
the private member is used.
In my opinion, the two versions of interface can be optimized
by the compiler and introduce no run-time burden.
My code need test and re-view.
Can anyone give me some advice?
Can anyone tell me whether there is a more graceful solution?
Any suggestion is welcome.
////////////////////////////////////////////////////////////////////
// Here is my code.
namespace common_utils_
{
template< typename T_Impl, bool T_UseRef >
struct si_root ;
template< typename T_Impl > struct si_root< T_Impl, true >
{
typedef T_Impl impl_t ;
si_root( void )
: m_pimpl( NULL )
{
}
void set_impl( impl_t* p )
{
m_pimpl = p ;
}
protected:
impl_t& impl( void )
{
assert( m_pimpl ) ;
return *m_pimpl ;
}
private:
impl_t* m_pimpl ;
} ;
template< typename T_Impl > struct si_root< T_Impl, false >
{
typedef T_Impl impl_t ;
protected:
impl_t& impl( void )
{
return m_impl ;
}
private:
impl_t m_impl ;
} ;
//
#define STATIC_INTERFACE_1(impl,T0) \
T0< si_root<impl,true> >
#define STATIC_INTERFACE_2(impl,T0,T1) \
T0< STATIC_INTERFACE_1(impl,T1) >
#define STATIC_INTERFACE_3(impl,T0,T1,T2) \
T0< STATIC_INTERFACE_2(impl,T1,T2) >
#define STATIC_INTERFACE_4(impl,T0,T1,T2,T3) \
T0< STATIC_INTERFACE_3(impl,T1,T2,T3) >
#define STATIC_CONCEPT_1(impl,T0) \
T0< si_root<impl,false> >
#define STATIC_CONCEPT_2(impl,T0,T1) \
T0< STATIC_CONCEPT_1(impl,T1) >
#define STATIC_CONCEPT_3(impl,T0,T1,T2) \
T0< STATIC_CONCEPT_2(impl,T1,T2) >
#define STATIC_CONCEPT_4(impl,T0,T1,T2,T3) \
T0< STATIC_CONCEPT_3(impl,T1,T2,T3) >
// exampls
namespace
{
template< typename T_Base > struct si_0 : public T_Base
{
typedef typename T_Base::impl_t::type_0 type_0 ;
void function0( void )
{
T_Base::impl().function0() ;
}
} ;
template< typename T_Base > struct si_1 : public T_Base
{
typedef typename T_Base::impl_t::type_1 type_1 ;
void function1( void )
{
T_Base::impl().function1() ;
}
} ;
template< typename T_Base > struct si_2 : public T_Base
{
typedef typename T_Base::impl_t::type_2 type_2 ;
void function2( void )
{
T_Base::impl().function2() ;
}
} ;
template< typename T_Base > struct si_3 : public T_Base
{
typedef typename T_Base::impl_t::type_3 type_3 ;
void function3( void )
{
T_Base::impl().function3() ;
}
} ;
struct TTTT
{
typedef int type_0 ;
typedef long type_1 ;
typedef float type_2 ;
typedef double type_3 ;
void function0( void )
{
std::cout << __LINE__ << ": " << __FUNCTION__ << " Is called."
<< std::endl ;
}
void function1( void )
{
std::cout << __LINE__ << ": " << __FUNCTION__ << " Is called."
<< std::endl ;
}
void function2( void )
{
std::cout << __LINE__ << ": " << __FUNCTION__ << " Is called."
<< std::endl ;
}
void function3( void )
{
std::cout << __LINE__ << ": " << __FUNCTION__ << " Is called."
<< std::endl ;
}
} ;
typedef STATIC_INTERFACE_4( TTTT, si_0, si_1, si_2, si_3 )
my_interface_t ;
typedef STATIC_CONCEPT_4( TTTT, si_0, si_1, si_2, si_3 )
my_concept_t ;
void interface_test( void )
{
TTTT obj ;
my_interface_t i ;
my_concept_t c ;
i.set_impl( &obj ) ;
i.function0() ;
i.function1() ;
i.function2() ;
i.function3() ;
c.function0() ;
c.function1() ;
c.function2() ;
c.function3() ;
}
} // anonymous
} // namespace common_utils_