/docs/MyDocs

To get this branch, use:
bzr branch http://darksoft.org/webbzr/docs/MyDocs

« back to all changes in this revision

Viewing changes to Development/languages/C/Samples.CPP/allocators.cpp

  • Committer: Suren A. Chilingaryan
  • Date: 2009-04-09 03:21:08 UTC
  • Revision ID: csa@dside.dyndns.org-20090409032108-w4edamdh4adrgdu3
import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <iostream>
 
2
#include <iterator>
 
3
#include <vector>
 
4
#include <memory>
 
5
 
 
6
 
 
7
  /* Compiler dependent. Certain compilers may inline operator new, in that
 
8
  case this will not replace default allocator */
 
9
void* operator new(size_t bytes) throw(std::bad_alloc) {
 
10
    std::cout << "GlobalAlloc(new): " << bytes << std::endl;
 
11
    return malloc(bytes);
 
12
}
 
13
 
 
14
//template <typename T> class DSAllocator;
 
15
 
 
16
template <typename T>
 
17
class DSAllocator : public std::allocator<T> {
 
18
 public:
 
19
    typedef size_t size_type;
 
20
    typedef T* pointer;
 
21
 
 
22
    template<typename U> struct rebind { typedef DSAllocator<U> other; };
 
23
 
 
24
 
 
25
    DSAllocator() : std::allocator<T>() { 
 
26
        std::cout << "Constructor " << typeid(T).name() << "()" << std::endl; 
 
27
    }
 
28
 
 
29
   ~DSAllocator() { 
 
30
        std::cout << "Destructor " << typeid(T).name() << "()" << std::endl; 
 
31
    }
 
32
 
 
33
    DSAllocator(const DSAllocator &a) : std::allocator<T>(a) { 
 
34
        std::cout << "Constructor " << typeid(T).name() << "(a)" << std::endl; 
 
35
    }
 
36
 
 
37
    template <typename U>
 
38
    DSAllocator(const DSAllocator<U> &a) : std::allocator<T>(a) { 
 
39
        std::cout << "Constructor " << typeid(T).name() << "(U a)" << std::endl; 
 
40
    }
 
41
 
 
42
    pointer allocate(size_type cnt, typename std::allocator<void>::const_pointer hint = 0) {
 
43
        std::cout << "Allocating: " << cnt << '*' << typeid(T).name() << "(" << sizeof(T) << ")" << std::endl;
 
44
        return std::allocator<T>::allocate(cnt, hint);
 
45
    }
 
46
    
 
47
    void deallocate(pointer p, size_type cnt) {
 
48
        std::cout << "Deallocating: " << cnt << '*' << typeid(T).name() << "(" << sizeof(T) << ")" << std::endl;
 
49
        return std::allocator<T>::deallocate(p, cnt);
 
50
    }
 
51
    
 
52
    void construct(pointer p, const T& val) {
 
53
        std::cout << "Init" << std::endl;
 
54
        std::allocator<T>::construct(p, val);
 
55
    }
 
56
    
 
57
    void destroy(pointer p) {
 
58
        std::cout << "Destroy" << std::endl;
 
59
        std::allocator<T>::destroy(p);
 
60
    }
 
61
 
 
62
};
 
63
 
 
64
//template <typename T> class DSAllocator2;
 
65
 
 
66
template <typename T>
 
67
class DSAllocator2  {
 
68
 public:
 
69
    typedef size_t size_type;
 
70
    typedef ptrdiff_t difference_type;
 
71
    typedef T* pointer;
 
72
    typedef const T* const_pointer;
 
73
    typedef T& reference;
 
74
    typedef const T& const_reference;
 
75
    typedef T value_type;
 
76
    
 
77
    std::allocator<T> *alloc;
 
78
 
 
79
    template<typename U> struct rebind { typedef DSAllocator2<U> other; };
 
80
 
 
81
 
 
82
    DSAllocator2() { 
 
83
        std::cout << "Constructor " << typeid(T).name() << "()" << ", " << this << std::endl; 
 
84
        alloc = new std::allocator<T>();
 
85
    }
 
86
 
 
87
   ~DSAllocator2() { 
 
88
        std::cout << "Destructor " << typeid(T).name() << "()" << ", " << this << std::endl; 
 
89
        delete alloc;
 
90
    }
 
91
 
 
92
        /* if this function doesn't exist, everything looks fine, but segmentations
 
93
        occurs due to the fact, what instead of this constructor simply copy
 
94
        is running and 'alloc' is freed twice */
 
95
    DSAllocator2(const DSAllocator2 &a)  {
 
96
        std::cout << "Constructor " << typeid(T).name() << "(a)" << std::endl; 
 
97
        alloc = new std::allocator<T>(*a.alloc);
 
98
    }
 
99
 
 
100
    template <typename U> DSAllocator2(const std::allocator<U> &a)  { 
 
101
        std::cout << "Constructor " << typeid(T).name() << "(stdal)" << std::endl; 
 
102
        alloc = new std::allocator<T>(a);
 
103
    }
 
104
 
 
105
    pointer allocate(size_type cnt, typename std::allocator<void>::const_pointer hint = 0) {
 
106
        std::cout << "Allocating: " << cnt << '*' << typeid(T).name() << "(" << sizeof(T) << ")" << std::endl;
 
107
        return alloc->allocate(cnt, hint);
 
108
    }
 
109
    
 
110
    void deallocate(pointer p, size_type cnt) {
 
111
        std::cout << "Deallocating: " << cnt << '*' << typeid(T).name() << "(" << sizeof(T) << ")" << std::endl;
 
112
        return alloc->deallocate(p, cnt);
 
113
    }
 
114
    
 
115
    void construct(pointer p, const T& val) {
 
116
        std::cout << "Construct: " << typeid(T).name() << "(" << sizeof(T) << ")" << std::endl;
 
117
        alloc->construct(p, val);
 
118
    }
 
119
    
 
120
    void destroy(pointer p) {
 
121
        std::cout << "Destroy: " << typeid(T).name() << "(" << sizeof(T) << ")" << std::endl;
 
122
        alloc->destroy(p);
 
123
    }
 
124
    
 
125
    size_type max_size() const throw() {
 
126
        return alloc->max_size();
 
127
    }
 
128
    
 
129
    pointer address(reference r) const {
 
130
        return &r;
 
131
    }
 
132
    
 
133
    const pointer address(const_reference r) const {
 
134
        return &r;
 
135
    }
 
136
    
 
137
};
 
138
 
 
139
template<typename _T1, typename _T2>
 
140
inline bool operator==(const DSAllocator2<_T1>& a, const DSAllocator2<_T2>& b) {
 
141
    std::cout << &a << " == " << &b << std::endl;
 
142
    return true; 
 
143
}
 
144
template<typename _T1, typename _T2>
 
145
inline bool operator!=(const DSAllocator2<_T1>& a, const DSAllocator2<_T2>& b) {
 
146
    std::cout << &a << " != " << &b << std::endl;
 
147
    return false; 
 
148
}
 
149
 
 
150
 
 
151
using namespace std;
 
152
 
 
153
main() {
 
154
    typedef basic_string<char, char_traits<char>, DSAllocator<char> > ds_string1;
 
155
    typedef vector <ds_string1, DSAllocator<ds_string1> > ds_vector1;
 
156
 
 
157
    typedef basic_string<char, char_traits<char>, DSAllocator2<char> > ds_string;
 
158
    typedef vector <ds_string, DSAllocator<ds_string> > ds_vector;
 
159
 
 
160
 
 
161
    cout << "Inherited allocator works in vector, but not in string:" << endl;
 
162
    ds_vector1 *vec1 = new ds_vector1();
 
163
 
 
164
    char *c = (char*)malloc(50);
 
165
    strcpy(c, "xxx");
 
166
    ds_string1 str(c);
 
167
    strcpy(c, "zzz");
 
168
    free(c);
 
169
 
 
170
    vec1->push_back(str);
 
171
 
 
172
    delete vec1;
 
173
    cout << endl;
 
174
 
 
175
 
 
176
    cout << "New allocator works well:" << endl;
 
177
    ds_vector vec;
 
178
    vec.push_back("1");
 
179
    vec.push_back("xxxxxxxxxx");
 
180
}