2017-06-12 01:58:08 +03:00
|
|
|
////
|
2017-06-12 18:20:54 +03:00
|
|
|
Copyright 2005, 2006 Ion Gaztañaga
|
|
|
|
Copyright 2005, 2006, 2017 Peter Dimov
|
2017-06-12 01:58:08 +03:00
|
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
|
|
|
|
|
|
See accompanying file LICENSE_1_0.txt or copy at
|
|
|
|
http://www.boost.org/LICENSE_1_0.txt
|
|
|
|
////
|
|
|
|
|
|
|
|
[#pointer_to_other]
|
|
|
|
# pointer_to_other
|
|
|
|
:toc:
|
|
|
|
:toc-title:
|
2017-06-12 03:12:03 +03:00
|
|
|
:idprefix: pointer_to_other_
|
2017-06-12 01:58:08 +03:00
|
|
|
|
2017-06-12 18:20:54 +03:00
|
|
|
## Description
|
|
|
|
|
|
|
|
The `pointer_to_other` utility provides a way, given a source pointer type, to obtain a pointer of the same type
|
|
|
|
to another pointee type.
|
|
|
|
|
|
|
|
There is test/example code in link:../../test/pointer_to_other_test.cpp[pointer_to_other_test.cpp].
|
|
|
|
|
|
|
|
## Rationale
|
|
|
|
|
|
|
|
When building pointer independent classes, like memory managers, allocators, or containers, there is often a need to
|
|
|
|
define pointers generically, so that if a template parameter represents a pointer (for example, a raw or smart pointer
|
|
|
|
to an `int`), we can define another pointer of the same type to another pointee (a raw or smart pointer to a `float`.)
|
|
|
|
|
|
|
|
```
|
|
|
|
template <class IntPtr> class FloatPointerHolder
|
|
|
|
{
|
|
|
|
// Let's define a pointer to a float
|
|
|
|
|
|
|
|
typedef typename boost::pointer_to_other
|
|
|
|
<IntPtr, float>::type float_ptr_t;
|
|
|
|
|
|
|
|
float_ptr_t float_ptr;
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
## Synopsis
|
|
|
|
|
|
|
|
`pointer_to_other` is defined in `<boost/smart_ptr/pointer_to_other.hpp>`.
|
|
|
|
|
|
|
|
```
|
2017-06-15 21:23:06 +03:00
|
|
|
namespace boost {
|
2017-06-12 18:20:54 +03:00
|
|
|
|
2017-06-15 21:23:06 +03:00
|
|
|
template<class T, class U> struct pointer_to_other;
|
2017-06-12 18:20:54 +03:00
|
|
|
|
2017-06-15 21:23:06 +03:00
|
|
|
template<class T, class U,
|
|
|
|
template <class> class Sp>
|
|
|
|
struct pointer_to_other< Sp<T>, U >
|
|
|
|
{
|
|
|
|
typedef Sp<U> type;
|
|
|
|
};
|
2017-06-12 18:20:54 +03:00
|
|
|
|
2017-06-15 21:23:06 +03:00
|
|
|
template<class T, class T2, class U,
|
|
|
|
template <class, class> class Sp>
|
|
|
|
struct pointer_to_other< Sp<T, T2>, U >
|
|
|
|
{
|
2017-06-12 18:20:54 +03:00
|
|
|
typedef Sp<U, T2> type;
|
2017-06-15 21:23:06 +03:00
|
|
|
};
|
2017-06-12 18:20:54 +03:00
|
|
|
|
2017-06-15 21:23:06 +03:00
|
|
|
template<class T, class T2, class T3, class U,
|
|
|
|
template <class, class, class> class Sp>
|
|
|
|
struct pointer_to_other< Sp<T, T2, T3>, U >
|
|
|
|
{
|
2017-06-12 18:20:54 +03:00
|
|
|
typedef Sp<U, T2, T3> type;
|
2017-06-15 21:23:06 +03:00
|
|
|
};
|
2017-06-12 18:20:54 +03:00
|
|
|
|
2017-06-15 21:23:06 +03:00
|
|
|
template<class T, class U>
|
|
|
|
struct pointer_to_other< T*, U >
|
|
|
|
{
|
2017-06-12 18:20:54 +03:00
|
|
|
typedef U* type;
|
2017-06-15 21:23:06 +03:00
|
|
|
};
|
|
|
|
}
|
2017-06-12 18:20:54 +03:00
|
|
|
```
|
|
|
|
|
|
|
|
If these definitions are not correct for a specific smart pointer, we can define a specialization of `pointer_to_other`.
|
|
|
|
|
|
|
|
## Example
|
|
|
|
|
|
|
|
```
|
|
|
|
// Let's define a memory allocator that can
|
|
|
|
// work with raw and smart pointers
|
|
|
|
|
|
|
|
#include <boost/pointer_to_other.hpp>
|
|
|
|
|
|
|
|
template <class VoidPtr>
|
|
|
|
class memory_allocator
|
|
|
|
{
|
|
|
|
// Predefine a memory_block
|
|
|
|
|
|
|
|
struct block;
|
|
|
|
|
|
|
|
// Define a pointer to a memory_block from a void pointer
|
|
|
|
// If VoidPtr is void *, block_ptr_t is block*
|
|
|
|
// If VoidPtr is smart_ptr<void>, block_ptr_t is smart_ptr<block>
|
|
|
|
|
|
|
|
typedef typename boost::pointer_to_other
|
|
|
|
<VoidPtr, block>::type block_ptr_t;
|
|
|
|
|
|
|
|
struct block
|
|
|
|
{
|
|
|
|
std::size_t size;
|
|
|
|
block_ptr_t next_block;
|
|
|
|
};
|
|
|
|
|
|
|
|
block_ptr_t free_blocks;
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
As we can see, using `pointer_to_other` we can create pointer independent code.
|