Skip to content

Instantly share code, notes, and snippets.

@Nemikolh
Last active December 27, 2015 03:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nemikolh/7263805 to your computer and use it in GitHub Desktop.
Save Nemikolh/7263805 to your computer and use it in GitHub Desktop.
#include "ptr_like.hpp"
int main()
{
vector<int> t {1, 2};
}
#include <vector>
#include <type_traits>
#include <cstddef>
template<typename T>
struct ptr_like;
template<typename T>
typename ptr_like<T>::difference_type
operator-(const ptr_like<T>&, const ptr_like<T>&);
template<typename T>
ptr_like<T> operator+(const ptr_like<T>&, typename ptr_like<T>::difference_type);
template<typename T>
ptr_like<T> operator+(typename ptr_like<T>::difference_type, const ptr_like<T>&);
template<typename T>
ptr_like<T> operator+(const ptr_like<T>&, typename ptr_like<T>::size_type);
template<typename T>
ptr_like<T> operator+(typename ptr_like<T>::size_type, const ptr_like<T>&);
template<typename T>
ptr_like<T> operator-(const ptr_like<T>&, typename ptr_like<T>::difference_type);
template<typename T>
bool operator<(const ptr_like<T>&, const ptr_like<T>&);
template<typename T>
bool operator>(const ptr_like<T>&, const ptr_like<T>&);
template<typename T>
bool operator>=(const ptr_like<T>&, const ptr_like<T>&);
template<typename T>
bool operator<=(const ptr_like<T>&, const ptr_like<T>&);
template<typename T>
bool operator==(const ptr_like<T>&, const ptr_like<T>&);
template<typename T>
bool operator!=(const ptr_like<T>&, const ptr_like<T>&);
namespace detail {
template<typename T>
struct ptr_like {
// Typedefs
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
// Ctors, ...
ptr_like(const ptr_like&) = default;
template<typename U, typename = typename
std::enable_if<std::is_convertible<U*, T*>::value>::type>
ptr_like(const ptr_like<U>& rhs);
template<typename U, typename = typename
std::enable_if<std::is_convertible<U*, T*>::value>::type>
ptr_like(ptr_like<U>&&);
ptr_like& operator= (const ptr_like&);
ptr_like& operator= (ptr_like&&);
// NullablePointer requirements
ptr_like(std::nullptr_t = nullptr);
ptr_like& operator= (std::nullptr_t);
// RandomAccessIterator requirements
pointer operator->() const;
ptr_like& operator++();
ptr_like operator++(int);
ptr_like& operator--();
ptr_like operator--(int);
ptr_like& operator+=(const difference_type&);
ptr_like operator+ (const difference_type&) const;
ptr_like& operator-=(const difference_type&);
ptr_like operator- (const difference_type&) const;
// Other found requirements
operator bool() const; // Comment to see the other error message.
// Correction :
// explicit operator bool() const;
};
}
template<>
struct ptr_like<void> : public detail::ptr_like<void> {
typedef std::ptrdiff_t difference_type;
};
template<typename T>
struct ptr_like : public detail::ptr_like<T> {
typedef detail::ptr_like<T> base_type;
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef T * pointer;
typedef T& reference;
typedef size_t size_type;
typedef std::random_access_iterator_tag iterator_category;
// Get access to base constructors
using base_type::base_type;
reference operator*() const;
reference operator[](const difference_type&) const;
};
template<typename T>
struct allocator {
typedef ptr_like<T> pointer;
typedef const ptr_like<T> const_pointer;
typedef ptr_like<void> void_pointer;
typedef const ptr_like<void> const_void_pointer;
typedef T value_type;
typedef size_t size_type;
typedef typename pointer::difference_type
difference_type;
template<typename U>
struct rebind
{
typedef allocator<U> other;
};
allocator(allocator&&) = default;
allocator(const allocator& ) = default;
allocator() = default;
template<typename T2>
allocator(const allocator<T2>&);
pointer allocate(size_type, const_pointer = nullptr);
void deallocate(pointer, size_type);
};
template<typename T, typename U>
inline bool operator==(allocator<T> a, allocator<U> b)
{ return true; }
template<typename T, typename U>
inline bool operator!=(allocator<T> a, allocator<U> b)
{ return false; }
template<typename T>
using vector = std::vector<T, allocator<T>>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment