extptr_allocator.h: Minor tweaks.

2008-11-11  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/ext/extptr_allocator.h: Minor tweaks.
	* include/ext/pointer.h: Likewise.
	* include/ext/cast.h: Likewise.

From-SVN: r141764
This commit is contained in:
Paolo Carlini 2008-11-11 12:15:59 +00:00 committed by Paolo Carlini
parent ddb47467a2
commit 8d8a4e9d3d
4 changed files with 115 additions and 162 deletions

View File

@ -1,3 +1,9 @@
2008-11-11 Paolo Carlini <paolo.carlini@oracle.com>
* include/ext/extptr_allocator.h: Minor tweaks.
* include/ext/pointer.h: Likewise.
* include/ext/cast.h: Likewise.
2008-11-10 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/38067

View File

@ -27,8 +27,8 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#ifndef _EXT_CAST_
#define _EXT_CAST_ 1
#ifndef _CAST_H
#define _CAST_H 1
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx);
@ -48,14 +48,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx);
*/
template<typename _ToType>
struct _Caster
{
typedef typename _ToType::element_type* type;
};
{ typedef typename _ToType::element_type* type; };
template<typename _ToType>
struct _Caster<_ToType*>
{
typedef _ToType* type;
};
{ typedef _ToType* type; };
/**
* Casting operations for cases where _FromType is not a standard pointer.
@ -118,4 +115,4 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx);
_GLIBCXX_END_NAMESPACE
#endif
#endif // _CAST_H

View File

@ -43,51 +43,26 @@
#include <limits>
#include <ext/pointer.h>
using __gnu_cxx::_Pointer_adapter;
using __gnu_cxx::_Relative_pointer_impl;
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
// forward declaration
template<typename _Tp>
class _ExtPtr_allocator;
// _ExtPtr_allocator<void> specialization.
template<>
class _ExtPtr_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void value_type;
// Note the non-standard pointer types
typedef _Pointer_adapter<_Relative_pointer_impl<void> > pointer;
typedef _Pointer_adapter<_Relative_pointer_impl<const void> >
const_pointer;
template<typename _Up>
struct rebind
{ typedef _ExtPtr_allocator<_Up> other; };
};
/**
* @brief An example allocator which uses a non-standard pointer type.
*
* This allocator specifies that containers use a 'relative pointer' as it's
* pointer type. (See bits/pointer.h) Memory allocation in this example
* pointer type. (See ext/pointer.h) Memory allocation in this example
* is still performed using std::allocator.
*/
template<typename _Tp>
class _ExtPtr_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
// Note the non-standard pointer types.
typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> > pointer;
typedef _Pointer_adapter<_Relative_pointer_impl<const _Tp> > const_pointer;
typedef _Pointer_adapter<_Relative_pointer_impl<const _Tp> >
const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
@ -103,7 +78,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
_ExtPtr_allocator(const _ExtPtr_allocator &__rarg) throw()
: _M_real_alloc(__rarg._M_real_alloc) { }
template<class _Up>
template<typename _Up>
_ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg) throw()
: _M_real_alloc(__rarg._M_getUnderlyingImp()) { }
@ -158,7 +133,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
template<typename _Up>
inline friend void
swap(_ExtPtr_allocator<_Up>& __larg, _ExtPtr_allocator<_Up>& __rarg);
swap(_ExtPtr_allocator<_Up>&, _ExtPtr_allocator<_Up>&);
// A method specific to this implementation.
const std::allocator<_Tp>&
@ -166,17 +141,38 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
{ return _M_real_alloc; }
private:
// simlated state data.
std::allocator<_Tp> _M_real_alloc;
};
// _ExtPtr_allocator<void> specialization.
template<>
class _ExtPtr_allocator<void>
{
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef void value_type;
// Note the non-standard pointer types
typedef _Pointer_adapter<_Relative_pointer_impl<void> > pointer;
typedef _Pointer_adapter<_Relative_pointer_impl<const void> >
const_pointer;
template<typename _Up>
struct rebind
{ typedef _ExtPtr_allocator<_Up> other; };
private:
std::allocator<void> _M_real_alloc;
};
template<typename _Tp>
inline void
swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg)
{
std::allocator<_Tp> temp( __rarg._M_real_alloc );
std::allocator<_Tp> __tmp( __rarg._M_real_alloc );
__rarg._M_real_alloc = __larg._M_real_alloc;
__larg._M_real_alloc = temp;
__larg._M_real_alloc = __tmp;
}
_GLIBCXX_END_NAMESPACE

View File

@ -1,7 +1,6 @@
// Custom pointer adapter and sample storage policies
// Copyright (C) 2008
// Free Software Foundation, Inc.
// Copyright (C) 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -33,23 +32,16 @@
* @author Bob Walters
*
* Provides reusable _Pointer_adapter for assisting in the development of
* custom pointer types that can be used with libstdc++ STL containers via
* custom pointer types that can be used with the standard containers via
* the allocator::pointer and allocator::const_pointer typedefs.
*/
#ifndef _EXT_POINTER_ADAPTER
#define _EXT_POINTER_ADAPTER 1
#ifndef _POINTER_H
#define _POINTER_H 1
#include <ostream>
#include <iosfwd>
#include <bits/stl_iterator_base_types.h>
#include <ext/cast.h>
#include <bits/concept_check.h>
// forward declaration of the iterator tag
namespace std {
struct random_access_iterator_tag;
};
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
@ -64,15 +56,15 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
* 4) An operator<() to support pointer comparison.
* 5) An operator==() to support pointer comparison.
*/
template<typename _Type>
template<typename _Tp>
class _Std_pointer_impl
{
public:
// the type this pointer points to.
typedef _Type element_type;
typedef _Tp element_type;
// A method to fetch the pointer value as a standard T* value;
inline _Type*
inline _Tp*
get() const
{ return _M_value; }
@ -94,7 +86,6 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
element_type* _M_value;
};
/**
* @brief A storage policy for use with _Pointer_adapter<> which stores
* the pointer's address as an offset value which is relative to
@ -108,27 +99,27 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
* As there is no reason why any normal pointer would point 1 byte into
* its own pointer address.
*/
template<typename _Type>
template<typename _Tp>
class _Relative_pointer_impl
{
public:
typedef _Type element_type;
typedef _Tp element_type;
_Type*
_Tp*
get() const
{
if (_M_diff == 1)
return NULL;
return 0;
else
return reinterpret_cast<_Type*>(
return reinterpret_cast<_Tp*>(
const_cast<char*>(reinterpret_cast<const char*>(this))
+ _M_diff);
}
void
set(_Type* __arg)
set(_Tp* __arg)
{
if (__arg == NULL)
if (!__arg)
_M_diff = 1;
else
_M_diff = reinterpret_cast<char*>(__arg)
@ -145,33 +136,33 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
{ return (this->get() == __rarg.get()); }
private:
ptrdiff_t _M_diff;
std::ptrdiff_t _M_diff;
};
/**
* Relative_pointer_impl needs a specialization for const T because of
* the casting done during pointer arithmetic.
*/
template<typename _Type>
class _Relative_pointer_impl<const _Type>
template<typename _Tp>
class _Relative_pointer_impl<const _Tp>
{
public:
typedef const _Type element_type;
typedef const _Tp element_type;
const _Type*
const _Tp*
get() const
{
if (_M_diff == 1)
return NULL;
return 0;
else
return reinterpret_cast<const _Type*>(
return reinterpret_cast<const _Tp*>(
(reinterpret_cast<const char*>(this)) + _M_diff);
}
void
set(const _Type* __arg)
set(const _Tp* __arg)
{
if (__arg == NULL)
if (!__arg)
_M_diff = 1;
else
_M_diff = reinterpret_cast<const char*>(__arg)
@ -188,10 +179,9 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
{ return (this->get() == __rarg.get()); }
private:
ptrdiff_t _M_diff;
std::ptrdiff_t _M_diff;
};
/**
* The specialization on this type helps resolve the problem of
* reference to void, and eliminates the need to specialize _Pointer_adapter
@ -201,34 +191,23 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
template<typename _Tp>
struct _Reference_type
{
typedef _Tp& reference;
};
{ typedef _Tp& reference; };
template<>
struct _Reference_type<void>
{
typedef _Invalid_type& reference;
};
{ typedef _Invalid_type& reference; };
template<>
struct _Reference_type<const void>
{
typedef const _Invalid_type& reference;
};
{ typedef const _Invalid_type& reference; };
template<>
struct _Reference_type<volatile void>
{
typedef volatile _Invalid_type& reference;
};
{ typedef volatile _Invalid_type& reference; };
template<>
struct _Reference_type<volatile const void>
{
typedef const volatile _Invalid_type& reference;
};
{ typedef const volatile _Invalid_type& reference; };
/**
* This structure accomodates the way in which std::iterator_traits<>
@ -236,35 +215,24 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
*/
template<typename _Tp>
struct _Unqualified_type
{
typedef _Tp type;
};
{ typedef _Tp type; };
template<typename _Tp>
struct _Unqualified_type<const _Tp>
{
typedef _Tp type;
};
{ typedef _Tp type; };
template<typename _Tp>
struct _Unqualified_type<volatile _Tp>
{
typedef volatile _Tp type;
};
{ typedef volatile _Tp type; };
template<typename _Tp>
struct _Unqualified_type<volatile const _Tp>
{
typedef volatile _Tp type;
};
{ typedef volatile _Tp type; };
/**
* The following provides an 'alternative pointer' that works with
* libstdc++-v3 containers when specified as the pointer typedef of the
* allocator.
*
* The following provides an 'alternative pointer' that works with the
* containers when specified as the pointer typedef of the allocator.
*
* The pointer type used with the containers doesn't have to be this class,
* but it must support the implicit conversions, pointer arithmetic,
* comparison operators, etc. that are supported by this class, and avoid
@ -290,50 +258,42 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
* _Tp* const == const _Pointer_adapter<_Std_pointer_impl<_Tp> >;
* const _Tp* const == const _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
*/
template<typename _Storage_policy >
template<typename _Storage_policy>
class _Pointer_adapter : public _Storage_policy
{
public:
typedef typename _Storage_policy::element_type element_type;
// These are needed for iterator_traits
typedef std::random_access_iterator_tag iterator_category;
typedef typename _Unqualified_type<element_type>::type value_type;
typedef ptrdiff_t difference_type;
typedef std::ptrdiff_t difference_type;
typedef _Pointer_adapter pointer;
typedef typename _Reference_type<element_type>::reference reference;
// Reminder: 'const' methods mean that the method is valid when the
// pointer is immutable, and has nothing to do with whether the
// 'pointee' is const.
// Default Constructor (Convert from element_type*)
_Pointer_adapter(element_type* __arg = NULL)
_Pointer_adapter(element_type* __arg = 0)
{ _Storage_policy::set(__arg); }
// Copy constructor from _Pointer_adapter of same type.
_Pointer_adapter(const _Pointer_adapter& __arg)
{ _Storage_policy::set(__arg.get()); }
// Convert from _Up* if conversion to element_type* is valid.
template<typename _Up>
_Pointer_adapter(_Up*__arg)
{
__glibcxx_function_requires(_ConvertibleConcept<element_type*, _Up*>);
_Storage_policy::set(__arg);
}
_Pointer_adapter(_Up* __arg)
{ _Storage_policy::set(__arg); }
// Conversion from another _Pointer_adapter if _Up if static cast is
// valid.
template<typename _Up>
_Pointer_adapter(const _Pointer_adapter<_Up>& __arg)
{
__glibcxx_function_requires(_ConvertibleConcept<element_type*,
typename _Pointer_adapter<_Up>::element_type*>);
_Storage_policy::set(__arg.get());
}
{ _Storage_policy::set(__arg.get()); }
// Destructor
~_Pointer_adapter() { }
@ -344,7 +304,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
_Storage_policy::set(__arg.get());
return *this;
}
template<typename _Up>
_Pointer_adapter&
operator=(const _Pointer_adapter<_Up>& __arg)
@ -365,17 +325,17 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
inline reference
operator*() const
{ return *(_Storage_policy::get()); }
// Operator->, returns element_type*
inline element_type*
operator->() const
{ return _Storage_policy::get(); }
// Operator[], returns a element_type& to the item at that loc.
inline reference
operator[](int __index) const
inline reference
operator[](std::ptrdiff_t __index) const
{ return _Storage_policy::get()[__index]; }
// To allow implicit conversion to "bool", for "if (ptr)..."
private:
typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const;
@ -388,9 +348,9 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
}
// ! operator (for: if (!ptr)...)
inline bool
inline bool
operator!() const
{ return (_Storage_policy::get()==NULL); }
{ return (_Storage_policy::get() == 0); }
// Pointer differences
inline friend std::ptrdiff_t
@ -401,12 +361,12 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
operator-(element_type* __lhs, const _Pointer_adapter& __rhs)
{ return (__lhs - __rhs.get()); }
template<class _Up>
template<typename _Up>
inline friend std::ptrdiff_t
operator-(const _Pointer_adapter& __lhs, _Up* __rhs)
{ return (__lhs.get() - __rhs); }
template<class _Up>
template<typename _Up>
inline friend std::ptrdiff_t
operator-(_Up* __lhs, const _Pointer_adapter& __rhs)
{ return (__lhs - __rhs.get()); }
@ -483,7 +443,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
}
inline _Pointer_adapter
operator--(int __unused)
operator--(int)
{
_Pointer_adapter tmp(*this);
_Storage_policy::set(_Storage_policy::get() - 1);
@ -520,7 +480,6 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
_GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>,);
_GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=,);
// These are here for expressions like "ptr == 0", "ptr != 0"
template<typename _Tp>
inline bool
@ -551,42 +510,37 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
operator==(const _Pointer_adapter<_Tp>& __lhs,
const _Pointer_adapter<_Tp>& __rhs)
{ return __lhs._Tp::operator==(__rhs); }
template<typename _Tp>
inline bool
operator<=(const _Pointer_adapter<_Tp>& __lhs,
const _Pointer_adapter<_Tp>& __rhs)
{ return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); }
template<typename _Tp>
inline bool
operator!=(const _Pointer_adapter<_Tp>& __lhs,
const _Pointer_adapter<_Tp>& __rhs)
{ return !(__lhs._Tp::operator==(__rhs)); }
template<typename _Tp>
inline bool
operator>(const _Pointer_adapter<_Tp>& __lhs,
const _Pointer_adapter<_Tp>& __rhs)
{ return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); }
template<typename _Tp>
inline bool
operator>=(const _Pointer_adapter<_Tp>& __lhs,
const _Pointer_adapter<_Tp>& __rhs)
{ return !(__lhs._Tp::operator<(__rhs)); }
template<class _CharT, class _Traits, class _StoreT>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits> &os,
const _Pointer_adapter<_StoreT>& __p)
{
os << __p.get();
return os;
}
template<typename _CharT, typename _Traits, typename _StoreT>
inline std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const _Pointer_adapter<_StoreT>& __p)
{ return (__os << __p.get()); }
_GLIBCXX_END_NAMESPACE
#endif /* _GCC_EXT_POINTER_ADAPTER */
#endif // _POINTER_H