1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_Allocator.h
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 30369 $
14  *---------------------------------------------------------------------------*/
15 
16 /*! @file
17   @brief アロケータに関するAPIの宣言
18 
19 */
20 #ifndef NN_FND_ALLOCATOR_H_
21 #define NN_FND_ALLOCATOR_H_
22 
23 #ifdef __cplusplus
24 
25 #include <new>
26 #include <limits>
27 #include <nn/util.h>
28 
29 namespace nn { namespace fnd {
30 
31 /*!
32     @brief ライブラリで使う汎用アロケータインターフェイスです。
33 */
34 class IAllocator
35 {
36 public:
37 
38     /*!
39         @brief 指定したサイズとアラインメントでメモリ領域を確保します。
40 
41         @param[in] size 確保するメモリのサイズ
42         @param[in] alignment 確保するメモリのアラインメント
43 
44         @return 確保したメモリ領域の先頭へのポインタ
45     */
46     virtual void* Allocate(size_t size, s32 alignment) = 0;
47 
48     /*!
49         @brief メモリ領域を解放します。
50 
51         @param[in] p 確保されているメモリ領域の先頭へのポインタ
52     */
53     virtual void Free(void* p) = 0;
54 
~IAllocator()55     virtual ~IAllocator() {}
56 };
57 
58 template <typename Allocator, typename Tag>
59 class StdAllocatorAdapterHolder
60 {
61 public:
62 
SetAllocator(Allocator allocator)63     static void SetAllocator(Allocator allocator) { s_Allocator = allocator; }
GetAllocator()64     static Allocator GetAllocator() { return s_Allocator; }
65 
66 private:
67     static Allocator s_Allocator;
68 };
69 
70 template <typename Allocator, typename T, typename Tag = void>
71 class StdAllocatorAdapter : public StdAllocatorAdapterHolder<Allocator, Tag>
72 {
73 public:
74 
75     typedef size_t size_type;
76     typedef sptr difference_type;
77     typedef T* pointer;
78     typedef const T* const_pointer;
79     typedef T& reference;
80     typedef const T& const_reference;
81     typedef T value_type;
82     template <class U> struct rebind { typedef StdAllocatorAdapter<Allocator, U, Tag> other; };
throw()83     StdAllocatorAdapter() throw() {}
throw()84     StdAllocatorAdapter(const StdAllocatorAdapter&) throw() {}
StdAllocatorAdapter(const StdAllocatorAdapter<Allocator,U,Tag> &)85     template <class U> StdAllocatorAdapter(const StdAllocatorAdapter<Allocator, U, Tag>&) throw() {}
throw()86     ~StdAllocatorAdapter() throw() {}
address(reference & x)87     pointer address(reference& x) const { return &x; }
address(const_reference & x)88     const_pointer address(const_reference& x) const { return &x; }
89     pointer allocate(size_type n, void* = 0) { return static_cast<T*>(StdAllocatorAdapterHolder<Allocator, Tag>::GetAllocator()->Allocate(n * sizeof(T), nn::util::alignment_of<T>::value)); }
deallocate(pointer p,size_type)90     void deallocate(pointer p, size_type) { StdAllocatorAdapterHolder<Allocator, Tag>::GetAllocator()->Free(static_cast<void*>(p)); }
max_size()91     size_type max_size() const throw() { return ::std::numeric_limits<size_type>::max() / sizeof(T); }
construct(pointer p,const T & val)92     void construct(pointer p, const T& val) { new (static_cast<void*>(p)) T(val); }
destroy(pointer p)93     void destroy(pointer p) { p->~T(); }
94 
95 };
96 
97 template <typename Allocator, typename T, typename Tag = void>
98 class StdUnitAllocatorAdapter
99 {
100 public:
101 
SetAllocator(Allocator allocator)102     static void SetAllocator(Allocator allocator) { s_Allocator = allocator; }
GetAllocator()103     static Allocator GetAllocator() { return s_Allocator; }
104 
105     typedef size_t size_type;
106     typedef sptr difference_type;
107     typedef T* pointer;
108     typedef const T* const_pointer;
109     typedef T& reference;
110     typedef const T& const_reference;
111     typedef T value_type;
112     template <class U> struct rebind { typedef StdUnitAllocatorAdapter<Allocator, U, Tag> other; };
throw()113     StdUnitAllocatorAdapter() throw() {}
throw()114     StdUnitAllocatorAdapter(const StdUnitAllocatorAdapter&) throw() {}
StdUnitAllocatorAdapter(const StdUnitAllocatorAdapter<Allocator,U,Tag> &)115     template <class U> StdUnitAllocatorAdapter(const StdUnitAllocatorAdapter<Allocator, U, Tag>&) throw() {}
throw()116     ~StdUnitAllocatorAdapter() throw() {}
address(reference & x)117     pointer address(reference& x) const { return &x; }
address(const_reference & x)118     const_pointer address(const_reference& x) const { return &x; }
119     pointer allocate(size_type n, void* = 0) { return static_cast<T*>(s_Allocator->Allocate(n * sizeof(T), nn::util::alignment_of<T>::value)); }
deallocate(pointer p,size_type)120     void deallocate(pointer p, size_type) { s_Allocator->Free(static_cast<void*>(p)); }
max_size()121     size_type max_size() const throw() { return ::std::numeric_limits<size_type>::max() / sizeof(T); }
construct(pointer p,const T & val)122     void construct(pointer p, const T& val) { new (static_cast<void*>(p)) T(val); }
destroy(pointer p)123     void destroy(pointer p) { p->~T(); }
124 
125 private:
126     static Allocator s_Allocator;
127 };
128 
129 template <typename Allocator, typename Tag>
130 Allocator StdAllocatorAdapterHolder<Allocator, Tag>::s_Allocator;
131 
132 template <typename Allocator, typename T, typename Tag>
133 Allocator StdUnitAllocatorAdapter<Allocator, T, Tag>::s_Allocator;
134 
135 }}	// end of namespace nn
136 
137 #endif // __cplusplus
138 
139 #endif
140