1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_Allocator.h
4 
5   Copyright (C)2009-2012 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: 47798 $
14  *---------------------------------------------------------------------------*/
15 
16 /* Please see man pages for details
17 
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 #include <nn/util/util_TypeTraits.h>
29 
30 namespace nn { namespace fnd {
31 
32 /* Please see man pages for details
33 
34 
35 
36 */
37 class IAllocator
38 {
39 public:
40 
41     /* Please see man pages for details
42 
43 
44 
45 
46 
47 
48     */
49     virtual void* Allocate(size_t size, s32 alignment) = 0;
50 
51     /* Please see man pages for details
52 
53 
54 
55     */
56     virtual void Free(void* p) = 0;
57 
~IAllocator()58     virtual ~IAllocator() {}
59 };
60 
61 template <typename Allocator, typename Tag>
62 class StdAllocatorAdapterHolder
63 {
64 public:
65 
SetAllocator(Allocator allocator)66     static void SetAllocator(Allocator allocator) { s_Allocator = allocator; }
GetAllocator()67     static Allocator GetAllocator() { return s_Allocator; }
68 
69 private:
70     static Allocator s_Allocator;
71 };
72 
73 template <typename Allocator, typename T, typename Tag = void>
74 class StdAllocatorAdapter : public StdAllocatorAdapterHolder<Allocator, Tag>
75 {
76 public:
77 
78     typedef size_t size_type;
79     typedef sptr difference_type;
80     typedef T* pointer;
81     typedef const T* const_pointer;
82     typedef T& reference;
83     typedef const T& const_reference;
84     typedef T value_type;
85     template <class U> struct rebind { typedef StdAllocatorAdapter<Allocator, U, Tag> other; };
throw()86     StdAllocatorAdapter() throw() {}
throw()87     StdAllocatorAdapter(const StdAllocatorAdapter&) throw() {}
StdAllocatorAdapter(const StdAllocatorAdapter<Allocator,U,Tag> &)88     template <class U> StdAllocatorAdapter(const StdAllocatorAdapter<Allocator, U, Tag>&) throw() {}
throw()89     ~StdAllocatorAdapter() throw() {}
address(reference & x)90     pointer address(reference& x) const { return &x; }
address(const_reference & x)91     const_pointer address(const_reference& x) const { return &x; }
92     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)93     void deallocate(pointer p, size_type) { StdAllocatorAdapterHolder<Allocator, Tag>::GetAllocator()->Free(static_cast<void*>(p)); }
max_size()94     size_type max_size() const throw() { return ::std::numeric_limits<size_type>::max() / sizeof(T); }
construct(pointer p,const T & val)95     void construct(pointer p, const T& val) { new (static_cast<void*>(p)) T(val); }
destroy(pointer p)96     void destroy(pointer p) { p->~T(); }
97 
98 };
99 
100 template <typename Allocator, typename T, typename Tag = void>
101 class StdUnitAllocatorAdapter
102 {
103 public:
104 
SetAllocator(Allocator allocator)105     static void SetAllocator(Allocator allocator) { s_Allocator = allocator; }
GetAllocator()106     static Allocator GetAllocator() { return s_Allocator; }
107 
108     typedef size_t size_type;
109     typedef sptr difference_type;
110     typedef T* pointer;
111     typedef const T* const_pointer;
112     typedef T& reference;
113     typedef const T& const_reference;
114     typedef T value_type;
115     template <class U> struct rebind { typedef StdUnitAllocatorAdapter<Allocator, U, Tag> other; };
throw()116     StdUnitAllocatorAdapter() throw() {}
throw()117     StdUnitAllocatorAdapter(const StdUnitAllocatorAdapter&) throw() {}
StdUnitAllocatorAdapter(const StdUnitAllocatorAdapter<Allocator,U,Tag> &)118     template <class U> StdUnitAllocatorAdapter(const StdUnitAllocatorAdapter<Allocator, U, Tag>&) throw() {}
throw()119     ~StdUnitAllocatorAdapter() throw() {}
address(reference & x)120     pointer address(reference& x) const { return &x; }
address(const_reference & x)121     const_pointer address(const_reference& x) const { return &x; }
122     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)123     void deallocate(pointer p, size_type) { s_Allocator->Free(static_cast<void*>(p)); }
max_size()124     size_type max_size() const throw() { return ::std::numeric_limits<size_type>::max() / sizeof(T); }
construct(pointer p,const T & val)125     void construct(pointer p, const T& val) { new (static_cast<void*>(p)) T(val); }
destroy(pointer p)126     void destroy(pointer p) { p->~T(); }
127 
128 private:
129     static Allocator s_Allocator;
130 };
131 
132 template <typename Allocator, typename Tag>
133 Allocator StdAllocatorAdapterHolder<Allocator, Tag>::s_Allocator;
134 
135 template <typename Allocator, typename T, typename Tag>
136 Allocator StdUnitAllocatorAdapter<Allocator, T, Tag>::s_Allocator;
137 
138 }}	// end of namespace nn
139 
140 #endif // __cplusplus
141 
142 #endif
143