// extract.hpp
#ifndef XTD_EXTRACT_HPP
#define XTD_EXTRACT_HPP
namespace xtd {
/*
template to be specialized for user defined types
*/
template < typename Type >
struct content
{
typedef Type type;
typedef type & reference;
static inline
reference
extractor( reference object )
{
return object;
}
};
/*
user entry point
*/
template < typename Type >
inline
typename content< Type >::reference
extract( Type & object )
{
return content< Type >::extractor( object );
}
/*
specializations for references and pointers
*/
template < typename Type >
struct content< Type & >
{
typedef typename content< Type >::type type;
typedef type & reference;
static inline
reference
extractor( Type & object )
{
return extract( object );
}
};
template < typename Type >
struct content< Type * >
{
typedef typename content< Type >::type type;
typedef type & reference;
static inline
reference
extractor( Type * object )
{
return extract( *object );
}
};
template < typename Type >
struct content< Type * const >
{
typedef typename content< Type >::type type;
typedef type & reference;
static inline
reference
extractor( Type * const object )
{
return extract( *object );
}
};
/*
generic function object
*/
struct extractor
{
template < typename Type >
inline
typename content< Type >::reference
operator ( ) ( Type & object )
{
return extract( object );
}
};
} // namespace xtd
#endif // XTD_EXTRACT_HPP
// pointer_example.cpp
#include <iostream>
#include "extract.hpp"
using namespace std;
using namespace xtd;
int
main( void )
{
int
i = 1024,
* p = &i,
** pp = &p,
*** ppp = &pp;
extract( ppp )++;
cout << extract( ppp ) << endl;
return 0;
}
// auto_pointer_specialization_example.cpp
#include <iostream>
#include <memory>
#include "extract.hpp"
namespace xtd {
template < typename Type >
struct content< std::auto_ptr< Type > >
{
typedef typename content< Type >::type type;
typedef type & reference;
static inline
reference
extractor( std::auto_ptr< Type > & object )
{
return extract( *object.get( ) );
}
};
template < typename Type >
struct content< std::auto_ptr< Type > const >
{
typedef typename content< Type >::type type;
typedef type & reference;
static inline
reference
extractor( std::auto_ptr< Type > const & object )
{
return extract( *object.get( ) );
}
};
} // namespace xtd
using namespace std;
using namespace xtd;
int
main( void )
{
auto_ptr< auto_ptr< int > >
ap( new auto_ptr< int >( new int( 1024 ) ) );
extract( ap )++;
cout << extract( ap ) << endl;
return 0;
}