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: 16565 $
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 };
55 
56 template <typename Allocator, typename Tag>
57 class StdAllocatorAdapterHolder
58 {
59 public:
60 
SetAllocator(Allocator allocator)61     static void SetAllocator(Allocator allocator) { s_Allocator = allocator; }
GetAllocator()62     static Allocator GetAllocator() { return s_Allocator; }
63 
64 private:
65     static Allocator s_Allocator;
66 };
67 
68 template <typename Allocator, typename T, typename Tag = void>
69 class StdAllocatorAdapter : public StdAllocatorAdapterHolder<Allocator, Tag>
70 {
71 public:
72 
73     typedef size_t size_type;
74     typedef sptr difference_type;
75     typedef T* pointer;
76     typedef const T* const_pointer;
77     typedef T& reference;
78     typedef const T& const_reference;
79     typedef T value_type;
80     template <class U> struct rebind { typedef StdAllocatorAdapter<Allocator, U, Tag> other; };
throw()81     StdAllocatorAdapter() throw() {}
throw()82     StdAllocatorAdapter(const StdAllocatorAdapter&) throw() {}
StdAllocatorAdapter(const StdAllocatorAdapter<Allocator,U,Tag> &)83     template <class U> StdAllocatorAdapter(const StdAllocatorAdapter<Allocator, U, Tag>&) throw() {}
throw()84     ~StdAllocatorAdapter() throw() {}
address(reference & x)85     pointer address(reference& x) const { return &x; }
address(const_reference & x)86     const_pointer address(const_reference& x) const { return &x; }
87     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)88     void deallocate(pointer p, size_type) { StdAllocatorAdapterHolder<Allocator, Tag>::GetAllocator()->Free(static_cast<void*>(p)); }
max_size()89     size_type max_size() const throw() { return ::std::numeric_limits<size_type>::max() / sizeof(T); }
construct(pointer p,const T & val)90     void construct(pointer p, const T& val) { new (static_cast<void*>(p)) T(val); }
destroy(pointer p)91     void destroy(pointer p) { p->~T(); }
92 
93 };
94 
95 template <typename Allocator, typename T, typename Tag = void>
96 class StdUnitAllocatorAdapter
97 {
98 public:
99 
SetAllocator(Allocator allocator)100     static void SetAllocator(Allocator allocator) { s_Allocator = allocator; }
GetAllocator()101     static Allocator GetAllocator() { return s_Allocator; }
102 
103     typedef size_t size_type;
104     typedef sptr difference_type;
105     typedef T* pointer;
106     typedef const T* const_pointer;
107     typedef T& reference;
108     typedef const T& const_reference;
109     typedef T value_type;
110     template <class U> struct rebind { typedef StdUnitAllocatorAdapter<Allocator, U, Tag> other; };
throw()111     StdUnitAllocatorAdapter() throw() {}
throw()112     StdUnitAllocatorAdapter(const StdUnitAllocatorAdapter&) throw() {}
StdUnitAllocatorAdapter(const StdUnitAllocatorAdapter<Allocator,U,Tag> &)113     template <class U> StdUnitAllocatorAdapter(const StdUnitAllocatorAdapter<Allocator, U, Tag>&) throw() {}
throw()114     ~StdUnitAllocatorAdapter() throw() {}
address(reference & x)115     pointer address(reference& x) const { return &x; }
address(const_reference & x)116     const_pointer address(const_reference& x) const { return &x; }
117     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)118     void deallocate(pointer p, size_type) { s_Allocator->Free(static_cast<void*>(p)); }
max_size()119     size_type max_size() const throw() { return ::std::numeric_limits<size_type>::max() / sizeof(T); }
construct(pointer p,const T & val)120     void construct(pointer p, const T& val) { new (static_cast<void*>(p)) T(val); }
destroy(pointer p)121     void destroy(pointer p) { p->~T(); }
122 
123 private:
124     static Allocator s_Allocator;
125 };
126 
127 template <typename Allocator, typename Tag>
128 Allocator StdAllocatorAdapterHolder<Allocator, Tag>::s_Allocator;
129 
130 template <typename Allocator, typename T, typename Tag>
131 Allocator StdUnitAllocatorAdapter<Allocator, T, Tag>::s_Allocator;
132 
133 }}	// end of namespace nn
134 
135 #endif // __cplusplus
136 
137 #endif
138