I am beginning to feel out place, if in order to compile some simple code I must make 4 questions to the respectfull audience. But it seems that the custom Allocator argument is paramount difficult, according to what I experience. I have defined a custom allocator very very simple. I have a typedef Char that may be char,char16_t,char32_t .
I defined a String that is an instantiation of basic_string.
I defined instances of that Class and the code correctly allocates them on the custom memory ( array named m - you may see it with the debugger).
The code works correctly with various sizes. By reading the code of basic_string and by seeing the memory arrangement, it is understood that the instances of basic_strings are just pointers to the allocated memory.
I defined too Vector as: vector<Char>
.
The problem is that sometimes the vector saves on custom memory and some times doesn't. Is it a bug or I don't understand the basic concepts ?
Vector vv={U'a',U'b',U'c',U'd',U'e',U'f',U'g',U'h'}; // doesn't assigns nothing
vv[0]=U'a'; // works correctly
vv[1]=U'b'; // works correctly
for(size_t i=0;vv0[i];i++)
vv.push_back(vv0[i]); // doesn't assign nothing.
The whole code is bellow:
//#include <bits/c++config.h>
//#define _GLIBCXX_FULLY_DYNAMIC_STRING 1
//#include <stdint.h> //#include <stddef.h> //#include <memory>
#include <iostream>
#include <string>
#include <limits>
#include <vector>
#define CONCAT_PURE(a,b,c) a ## b ## c
#define CONCAT(a,b,c) CONCAT_PURE(a,b,c)
typedef char char8_t; typedef char char64_t; // just for symmetry, char64 may exist when tokens are 64bit.
#define charSz 32 // may be 8,16,32,64 change by hand !
typedef CONCAT(char,charSz,_t) Char; // may be char8_t or char16_t or char32_t or char64_t
// the macro STR(xxxxx) permits us to write strings with characters of 8 bit 16 bit 32 bit (later on 64 bits)
#if charSz == 8
#define STR(s) #s
#elif charSz == 16
#define STR(s) u ## #s
#elif charSz == 32
#define STR(s) U ## #s
#elif charSz == 64
#define STR(s) UU ## #s
#endif
typedef int32_t Token;typedef unsigned char byte;
typedef size_t addr;addr freePos=0;Token freeT=0;
const size_t heapSize=0x400;byte m[heapSize];
addr Allocate(size_t sz){addr t=freePos;freePos+=sz;return t;} // justs increasing
void Deallocate(addr p,size_t sz){/**((size_t*)(m+p))=sz;*/} // not important actually
template <typename T>
struct Allocator {
// http://www.codeproject.com/Articles/4795/C-Standard-Allocator-An-Introduction-and-Implement
typedef T value_type;
typedef T* pointer; typedef const T* const_pointer;
typedef value_type& reference; typedef const value_type& const_reference;
typedef std::size_t size_type; typedef std::ptrdiff_t difference_type;
template<typename U> struct rebind{typedef Allocator<U> other;};
// The initialization of freePos and freeT is done independently of the class definition because doing
// it in the class creator another instance (with other template parameter would reinitialize them.
Allocator() {}
~Allocator() {}
template<typename U> Allocator(U){}
static inline pointer allocate(size_type n){return (pointer)(m+Allocate(n*sizeof(T)));}
static void deallocate(pointer p, size_type n){Deallocate((byte*)p-m,sizeof(T)*n);}
inline size_type max_size() const{return std::numeric_limits<size_type>::max() / sizeof(T);}
inline void construct(pointer p, const T& t) {}
inline void destroy(pointer p) {}
};
template <typename T>
bool operator==(Allocator<T> const &, Allocator<T> const &) { return true; }
template <typename T>
bool operator!=(Allocator<T> const &, Allocator<T> const &) { return false; }
typedef std::basic_string< Char,std::char_traits<Char>,Allocator<Char> > String;
typedef std::vector< Char,Allocator<Char> > Vector;
int main(){
// fill memory with values in order to be able to see modifications
for (size_t i=0;i<sizeof(m);i++) m[i]=0xDD;
String s;
String t;
String u;
s=STR(nice);
t=STR(very beautyfull);
u=STR(good);
Char vv0[]=U"looking_well";
Vector vv={U'a',U'b',U'c',U'd',U'e',U'f',U'g',U'h'};
vv[0]=U'a';
vv[1]=U'b';
for(size_t i=0;vv0[i];i++)
vv.push_back(vv0[i]);
return 0;
}