| //// |
| Copyright 2005, 2006 Ion Gaztañaga |
| Copyright 2005, 2006, 2017 Peter Dimov |
| |
| 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: |
| :idprefix: pointer_to_other_ |
| |
| ## 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>`. |
| |
| ``` |
| namespace boost { |
| |
| template<class T, class U> struct pointer_to_other; |
| |
| template<class T, class U, |
| template <class> class Sp> |
| struct pointer_to_other< Sp<T>, U > |
| { |
| typedef Sp<U> type; |
| }; |
| |
| template<class T, class T2, class U, |
| template <class, class> class Sp> |
| struct pointer_to_other< Sp<T, T2>, U > |
| { |
| typedef Sp<U, T2> type; |
| }; |
| |
| template<class T, class T2, class T3, class U, |
| template <class, class, class> class Sp> |
| struct pointer_to_other< Sp<T, T2, T3>, U > |
| { |
| typedef Sp<U, T2, T3> type; |
| }; |
| |
| template<class T, class U> |
| struct pointer_to_other< T*, U > |
| { |
| typedef U* type; |
| }; |
| } |
| ``` |
| |
| 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. |