#ifndef SASS_ALLOCATOR_H
#define SASS_ALLOCATOR_H
#include "config.hpp"
#include "../settings.hpp"
#include "../MurmurHash2.hpp"
#include <vector>
#include <limits>
#include <iostream>
#include <algorithm>
#include <functional>
namespace Sass {
#ifndef SASS_CUSTOM_ALLOCATOR
template <typename T> using Allocator = std::allocator<T>;
#else
void* allocateMem(size_t size);
void deallocateMem(void* ptr, size_t size = 1);
template<typename T>
class Allocator
{
public:
// Allocator traits
typedef T type;
typedef type value_type;
typedef value_type* pointer;
typedef value_type const* const_pointer;
typedef value_type& reference;
typedef value_type const& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
template<typename U>
struct rebind
{
typedef Allocator<U> other;
};
// Constructor
Allocator(void) {}
// Copy Constructor
template<typename U>
Allocator(Allocator<U> const&)
{}
// allocate but don't initialize count of elements of type T
pointer allocate(size_type count, const_pointer /* hint */ = 0)
{
return (pointer)(Sass::allocateMem(count * sizeof(T)));
}
// deallocate storage ptr of deleted elements
void deallocate(pointer ptr, size_type count)
{
Sass::deallocateMem(ptr, count);
}
// return maximum number of elements that can be allocated
size_type max_size() const throw()
{
return std::numeric_limits<size_type>::max() / sizeof(T);
}
// Address of object
type* address(type& obj) const { return &obj; }
type const* address(type const& obj) const { return &obj; }
// Construct object
void construct(type* ptr, type const& ref) const
{
// In-place copy construct
new(ptr) type(ref);
}
// Destroy object
void destroy(type* ptr) const
{
// Call destructor
ptr->~type();
}
};
template<typename T, typename U>
bool operator==(Allocator<T> const& left,
Allocator<U> const& right)
{
return true;
}
template<typename T, typename U>
bool operator!=(Allocator<T> const& left,
Allocator<U> const& right)
{
return !(left == right);
}
#endif
namespace sass {
template <typename T> using vector = std::vector<T, Sass::Allocator<T>>;
using string = std::basic_string<char, std::char_traits<char>, Sass::Allocator<char>>;
using sstream = std::basic_stringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
using ostream = std::basic_ostringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
using istream = std::basic_istringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
}
}
#ifdef SASS_CUSTOM_ALLOCATOR
namespace std {
// Only GCC seems to need this specialization!?
template <> struct hash<Sass::sass::string> {
public:
inline size_t operator()(
const Sass::sass::string& name) const
{
return MurmurHash2(
(void*)name.c_str(),
(int)name.size(),
0x73617373);
}
};
}
#endif
#endif