迭代器
my_iterator.h
#ifndef MY_ITERATOR_H
#define MY_ITERATOR_H
namespace Srh
{
typedef int ptrdiff_t;
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
template<typename _C, typename _Ty, typename _D = ptrdiff_t,
typename _Pointer = _Ty*, typename _Reference = _Ty&>
struct iterator
{
typedef _C iterator_category;
typedef _Ty value_type;
typedef _D difference_type;
typedef _Pointer pointer;
typedef _Reference reference;
};
template<typename _Iterator>
struct iterator_traits
{
typedef typename _Iterator::iterator_category iterator_category;
typedef typename _Iterator::value_type value_type;
typedef typename _Iterator::difference_type difference_type;
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
};
template<typename T>
struct iterator_traits<T*>
{
typedef typename random_access_iterator_tag iterator_category;
typedef typename T value_type;
typedef typename ptrdiff_t difference_type;
typedef typename T* pointer;
typedef typename T& reference;
};
template<typename T>
struct iterator_traits<const T*>
{
typedef typename random_access_iterator_tag iterator_category;
typedef typename T value_type;
typedef typename ptrdiff_t difference_type;
typedef typename const T* pointer;
typedef typename const T& reference;
};
template<typename _Iterator>
inline typename iterator_traits<_Iterator>::iterator_category
iterator_category(const _Iterator&) {
typedef typename iterator_traits<_Iterator>::iterator_category category;
return category();
}
template<typename _Iterator>
inline typename iterator_traits<_Iterator>::difference_type*
distance_type(const _Iterator&) {
return static_cast<typename iterator_traits<_Iterator>::difference_type*>(0);
}
template<typename _Iterator>
inline typename iterator_traits<_Iterator>::value_type*
value_type(const _Iterator&) {
return static_cast<typename iterator_traits<_Iterator>::value_type*>(0);
}
template<typename _Ty, typename _D = ptrdiff_t>
struct _Forit : public iterator<forward_iterator_tag, _Ty, _D> {};
template<typename _Ty, typename _D = ptrdiff_t>
struct _Bidit : public iterator<bidirectional_iterator_tag, _Ty, _D> {};
template<typename _Ty, typename _D = ptrdiff_t>
struct _Ranit : public iterator<random_access_iterator_tag, _Ty, _D> {};
template<typename _II, typename _D>
inline void __advance(_II& i, _D n, input_iterator_tag)
{
while (n--)
{
i++;
}
}
template<typename _BI, typename _D>
inline void __advance(_BI& i, _D n, bidirectional_iterator_tag)
{
if (n >= 0)
{
while (n--) ++i;
}
else
{
while (n++) --i;
}
}
template<typename _RAI, typename _D>
inline void __advance(_RAI& i, _D n, random_access_iterator_tag)
{
i += n;
}
template<typename _II, typename _D>
inline void advance(_II& i, _D n)
{
iterator_traits<_II>();
typedef typename iterator_traits<_II>::iterator_category cate;
__advance(i, n, cate());
}
template<typename _II>
inline typename iterator_traits<_II>::difference_type
__distance(_II _F, _II _L, input_iterator_tag)
{
typename iterator_traits<_II>::difference_type n = 0;
while (_F != _L)
{
_F++;
n++;
}
return n;
}
template<typename _RAI>
inline typename iterator_traits<_RAI>::difference_type
__distance(_RAI _F, _RAI _L, random_access_iterator_tag)
{
return _L - _F;
}
template<typename _II>
inline typename iterator_traits<_II>::difference_type
distance(_II _F, _II _L)
{
return __distance(_F, _L, iterator_category(_F));
}
}
#endif
类型萃取
my_type_traits.h
#ifndef MY_TYPE_TRAITS_H
#define MY_TYPE_TRAITS_H
namespace Srh
{
struct __true_type {};
struct __false_type {};
template<typename type>
struct __type_traits
{
typedef __true_type this_dummy_member_must_be_first;
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
template<> struct __type_traits<char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<signed char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<unsigned char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<short>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<unsigned short>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<int>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<unsigned int>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<long int>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<unsigned long int>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<long long>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<unsigned long long>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<float>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<double>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<> struct __type_traits<long double>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template<class T>
struct __type_traits<T*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
}
#endif
构造和析构
my_construct.h
#ifndef MY_CONSTRUCT_H
#define MY_CONSTRUCT_H
#include"my_iterator.h"
#include"my_type_traits.h"
namespace Srh
{
template<typename T1, typename T2>
inline void construct(T1* p, const T2& val)
{
new (p) T1(val);
}
template<typename T>
inline void construct(T* p)
{
new (p) T();
}
template<typename T>
inline void destroy(T* p)
{
p->~T();
}
template<typename _FI>
inline void __destroy_aux(_FI _F, _FI _L, Srh::__true_type)
{}
template<typename _FI>
inline void __destroy_aux(_FI _F, _FI _L, Srh::__false_type)
{
for (; _F != _L; ++_F)
{
destroy(&*_F);
}
}
template<typename _FI, typename T>
inline void __destroy(_FI _F, _FI _L, T*)
{
typedef typename Srh::__type_traits<T>::has_trivial_destructor dest;
__destroy_aux(_F, _L, dest());
}
template<typename _FI>
inline void destroy(_FI _F, _FI _L)
{
__destroy(_F, _L, Srh::value_type(_F));
}
}
#endif
空间配置器
my_alloc.h
#ifndef MY_ALLOC_H
#define MY_ALLOC_H
#include<iostream>
using namespace std;
namespace Srh
{
#if 0
#include<new>
#define __THROW_BAD_ALLOC throw std::bad_alloc;
#elif !defined(__THROW_BAD_ALLOC)
#define __THROW_BAD_ALLOC std::cerr << "out of memory" << std::endl; exit(1);
#endif
template<int inst>
class __malloc_alloc_template
{
public:
using PFUN = void (*)();
private:
static void* oom_malloc(size_t n)
{
void* result = nullptr;
void (*my_malloc_handler) () = nullptr;
for (; ;)
{
my_malloc_handler = __malloc_alloc_oom_handler;
if (nullptr == my_malloc_handler)
{
__THROW_BAD_ALLOC;
}
my_malloc_handler();
result = malloc(n);
if (nullptr != result)
{
return result;
}
}
}
static void* oom_realloc(void* p, size_t new_sz)
{
void* result = nullptr;
void (*my_malloc_handler) () = nullptr;
for (; ;)
{
my_malloc_handler = __malloc_alloc_oom_handler;
if (nullptr == my_malloc_handler)
{
__THROW_BAD_ALLOC;
}
my_malloc_handler();
result = realloc(p, new_sz);
if (nullptr != result)
{
return result;
}
}
}
static PFUN __malloc_alloc_oom_handler;
public:
static void* allocate(size_t n)
{
void* result = malloc(n);
if (nullptr == result)
{
result = oom_malloc(n);
}
return result;
}
static void deallocate(void* p, size_t n)
{
free(p);
}
static void* reallocate(void* p, size_t old_sz, size_t new_sz)
{
void* result = realloc(p, new_sz);
if (nullptr == result)
{
result = oom_realloc(p, new_sz);
}
return result;
}
static PFUN set_malloc_handler(PFUN p)
{
PFUN old = __malloc_alloc_oom_handler;
__malloc_alloc_oom_handler = p;
return old;
}
};
template<int inst>
typename __malloc_alloc_template<inst>::PFUN
__malloc_alloc_template<inst>::__malloc_alloc_oom_handler = nullptr;
using malloc_alloc = __malloc_alloc_template<0>;
enum { __ALIGN = 8 };
enum { __MAX_BYTES = 128 };
enum { __NFREELISTS = __MAX_BYTES / __ALIGN };
template<bool threads, int inst>
class __default_alloc_template
{
private:
union obj
{
union obj* free_list_link;
char client_data[1];
};
private:
static obj* volatile free_list[__NFREELISTS];
static size_t ROUND_UP(size_t bytes)
{
return (bytes + __ALIGN - 1) & ~(__ALIGN - 1);
}
static size_t FREELIST_INDEX(size_t bytes)
{
return (bytes + __ALIGN - 1) / __ALIGN - 1;
}
static char* start_free;
static char* end_free;
static size_t heap_size;
static char* chunk_alloc(size_t size, int& nobjs)
{
char* result = nullptr;
size_t total_bytes = size * nobjs;
size_t bytes_left = end_free - start_free;
if (bytes_left >= total_bytes)
{
result = start_free;
start_free = start_free + total_bytes;
return result;
}
else if (bytes_left >= size)
{
nobjs = bytes_left / size;
result = start_free;
start_free = start_free + total_bytes;
return result;
}
else
{
size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
if (bytes_left > 0)
{
obj* volatile* my_free_list = free_list + FREELIST_INDEX(bytes_left);
((obj*)start_free)->free_list_link = *my_free_list;
*my_free_list = (obj*)start_free;
}
start_free = (char*)malloc(bytes_to_get);
if (nullptr == start_free)
{
obj* volatile* my_free_list = nullptr;
obj* p = nullptr;
for (int i = size; i <= __MAX_BYTES; i += __ALIGN)
{
my_free_list = free_list + FREELIST_INDEX(i);
p = *my_free_list;
if (nullptr != p)
{
*my_free_list = p->free_list_link;
start_free = (char*)p;
end_free = start_free + i;
return chunk_alloc(size, nobjs);
}
}
end_free = 0;
start_free = (char*)malloc_alloc::allocate(bytes_to_get);
}
end_free = start_free + bytes_to_get;
heap_size += bytes_to_get;
return chunk_alloc(size, nobjs);
}
}
static void* refill(size_t size)
{
int nobjs = 20;
char* chunk = chunk_alloc(size, nobjs);
if (1 == nobjs) return chunk;
obj* volatile* my_free_list = nullptr;
obj* result = (obj*)chunk;
obj* current_obj = nullptr;
obj* next_obj = nullptr;
int i = 0;
my_free_list = free_list + FREELIST_INDEX(size);
*my_free_list = next_obj = (obj*)(chunk + size);
for (i = 1; ; ++i)
{
current_obj = next_obj;
next_obj = (obj*)((char*)next_obj + size);
if (i == nobjs - 1)
{
current_obj->free_list_link = nullptr;
break;
}
current_obj->free_list_link = next_obj;
}
return result;
}
public:
static void* allocate(size_t size)
{
if (size > (size_t)__MAX_BYTES)
{
return malloc_alloc::allocate(size);
}
obj* result = nullptr;
obj* volatile* my_free_list = nullptr;
my_free_list = free_list + FREELIST_INDEX(size);
result = *my_free_list;
if (nullptr == result)
{
void* r = refill(ROUND_UP(size));
return r;
}
*my_free_list = result->free_list_link;
return result;
}
static void deallocate(void* p, size_t n)
{
if (n > (size_t)__MAX_BYTES)
{
return malloc_alloc::deallocate(p, n);
}
obj* q = (obj*)p;
obj* volatile* my_free_list = nullptr;
my_free_list = free_list + FREELIST_INDEX(n);
q->free_list_link = *my_free_list;
*my_free_list = q;
}
static void* reallocate(void* p, size_t old_sz, size_t new_sz)
{
if (old_sz > (size_t)__MAX_BYTES && new_sz > (size_t)__MAX_BYTES)
{
return malloc_alloc::reallocate(p, old_sz, new_sz);
}
if (ROUND_UP(old_sz) == ROUND_UP(new_sz))
{
return p;
}
size_t sz = old_sz < new_sz ? old_sz : new_sz;
void* s = allocate(new_sz);
memmove(s, p, sz);
deallocate(p, old_sz);
return s;
}
};
template<bool threads, int inst>
typename __default_alloc_template<threads, inst>::obj* volatile
__default_alloc_template<threads, inst>::free_list[__NFREELISTS] = {};
template<bool threads, int inst>
char* __default_alloc_template<threads, inst>::start_free = nullptr;
template<bool threads, int inst>
char* __default_alloc_template<threads, inst>::end_free = nullptr;
template<bool threads, int inst>
size_t __default_alloc_template<threads, inst>::heap_size = 0;
#ifdef __USE_MALLOC
typedef __malloc_alloc_template<0> malloc_alloc;
typedef malloc_alloc alloc;
#else
typedef __default_alloc_template<0, 0> alloc;
#endif
template<typename T, typename Alloc>
class simple_alloc
{
public:
static T* allocate(size_t n)
{
return Alloc::allocate(sizeof(T) * n);
}
static T* allocate()
{
return Alloc::allocate(sizeof(T));
}
void deallocate(T* p, size_t n)
{
if (nullptr == p) return;
Alloc::deallocate(p, size(T) * n);
}
void deallocate(T* p)
{
if (nullptr == p) return;
Alloc::deallocate(p, sizeof(T));
}
};
}
#endif