From eec721826cc35a0c08dc5bc54db9a51dbd4fa361 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Fri, 28 Jun 2013 16:59:19 +0000 Subject: Implement full support for non-pointer pointers in custom allocators for string. This completes the custom pointer support for the entire library. llvm-svn: 185167 --- libcxx/test/strings/basic.string/min_allocator.h | 252 +++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 libcxx/test/strings/basic.string/min_allocator.h (limited to 'libcxx/test/strings/basic.string/min_allocator.h') diff --git a/libcxx/test/strings/basic.string/min_allocator.h b/libcxx/test/strings/basic.string/min_allocator.h new file mode 100644 index 00000000000..c0d28e5faa2 --- /dev/null +++ b/libcxx/test/strings/basic.string/min_allocator.h @@ -0,0 +1,252 @@ +#ifndef MIN_ALLOCATOR_H +#define MIN_ALLOCATOR_H + +#if __cplusplus >= 201103L + +#include + +template class min_pointer; +template class min_pointer; +template <> class min_pointer; +template <> class min_pointer; +template class min_allocator; + +template <> +class min_pointer +{ + const void* ptr_; +public: + min_pointer() noexcept = default; + min_pointer(std::nullptr_t) : ptr_(nullptr) {} + template + min_pointer(min_pointer p) : ptr_(p.ptr_) {} + + explicit operator bool() const {return ptr_ != nullptr;} + + friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} + friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} + template friend class min_pointer; +}; + +template <> +class min_pointer +{ + void* ptr_; +public: + min_pointer() noexcept = default; + min_pointer(std::nullptr_t) : ptr_(nullptr) {} + template ::value + >::type + > + min_pointer(min_pointer p) : ptr_(p.ptr_) {} + + explicit operator bool() const {return ptr_ != nullptr;} + + friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} + friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} + template friend class min_pointer; +}; + +template +class min_pointer +{ + T* ptr_; + + explicit min_pointer(T* p) : ptr_(p) {} +public: + min_pointer() noexcept = default; + min_pointer(std::nullptr_t) : ptr_(nullptr) {} + explicit min_pointer(min_pointer p) : ptr_(static_cast(p.ptr_)) {} + + explicit operator bool() const {return ptr_ != nullptr;} + + typedef std::ptrdiff_t difference_type; + typedef T& reference; + typedef T* pointer; + typedef T value_type; + typedef std::random_access_iterator_tag iterator_category; + + reference operator*() const {return *ptr_;} + pointer operator->() const {return ptr_;} + + min_pointer& operator++() {++ptr_; return *this;} + min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;} + + min_pointer& operator--() {--ptr_; return *this;} + min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;} + + min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;} + min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;} + + min_pointer operator+(difference_type n) const + { + min_pointer tmp(*this); + tmp += n; + return tmp; + } + + friend min_pointer operator+(difference_type n, min_pointer x) + { + return x + n; + } + + min_pointer operator-(difference_type n) const + { + min_pointer tmp(*this); + tmp -= n; + return tmp; + } + + friend difference_type operator-(min_pointer x, min_pointer y) + { + return x.ptr_ - y.ptr_; + } + + reference operator[](difference_type n) const {return ptr_[n];} + + friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;} + friend bool operator> (min_pointer x, min_pointer y) {return y < x;} + friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);} + friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);} + + static min_pointer pointer_to(T& t) {return min_pointer(std::addressof(t));} + + friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} + friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} + template friend class min_pointer; + template friend class min_allocator; +}; + +template +class min_pointer +{ + const T* ptr_; + + explicit min_pointer(const T* p) : ptr_(p) {} +public: + min_pointer() noexcept = default; + min_pointer(std::nullptr_t) : ptr_(nullptr) {} + min_pointer(min_pointer p) : ptr_(p.ptr_) {} + explicit min_pointer(min_pointer p) : ptr_(static_cast(p.ptr_)) {} + + explicit operator bool() const {return ptr_ != nullptr;} + + typedef std::ptrdiff_t difference_type; + typedef const T& reference; + typedef const T* pointer; + typedef const T value_type; + typedef std::random_access_iterator_tag iterator_category; + + reference operator*() const {return *ptr_;} + pointer operator->() const {return ptr_;} + + min_pointer& operator++() {++ptr_; return *this;} + min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;} + + min_pointer& operator--() {--ptr_; return *this;} + min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;} + + min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;} + min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;} + + min_pointer operator+(difference_type n) const + { + min_pointer tmp(*this); + tmp += n; + return tmp; + } + + friend min_pointer operator+(difference_type n, min_pointer x) + { + return x + n; + } + + min_pointer operator-(difference_type n) const + { + min_pointer tmp(*this); + tmp -= n; + return tmp; + } + + friend difference_type operator-(min_pointer x, min_pointer y) + { + return x.ptr_ - y.ptr_; + } + + reference operator[](difference_type n) const {return ptr_[n];} + + friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;} + friend bool operator> (min_pointer x, min_pointer y) {return y < x;} + friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);} + friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);} + + static min_pointer pointer_to(const T& t) {return min_pointer(std::addressof(t));} + + friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} + friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} + template friend class min_pointer; +}; + +template +inline +bool +operator==(min_pointer x, std::nullptr_t) +{ + return !static_cast(x); +} + +template +inline +bool +operator==(std::nullptr_t, min_pointer x) +{ + return !static_cast(x); +} + +template +inline +bool +operator!=(min_pointer x, std::nullptr_t) +{ + return static_cast(x); +} + +template +inline +bool +operator!=(std::nullptr_t, min_pointer x) +{ + return static_cast(x); +} + +template +class min_allocator +{ +public: + typedef T value_type; + typedef min_pointer pointer; + + min_allocator() = default; + template + min_allocator(min_allocator) {} + + pointer allocate(std::ptrdiff_t n) + { + return pointer(static_cast(::operator new(n*sizeof(T)))); + } + + void deallocate(pointer p, std::ptrdiff_t) + { + return ::operator delete(p.ptr_); + } + + friend bool operator==(min_allocator, min_allocator) {return true;} + friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);} +}; + +#endif // __cplusplus >= 201103L + +#endif // MIN_ALLOCATOR_H -- cgit v1.2.3