last changes from bloomberg.
This commit is contained in:
106
cpp/cpp11/trnx_vector_impl.h
Normal file
106
cpp/cpp11/trnx_vector_impl.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef INCLUDED_TRNX_VECTOR_IMPL
|
||||
#define INCLUDED_TRNX_VECTOR_IMPL
|
||||
|
||||
#include <cstddef>
|
||||
#include <exception>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace trnx {
|
||||
namespace detail {
|
||||
|
||||
// This union is not meant to be shown/completely understood from the students.
|
||||
//
|
||||
// They should know that `uninitialized<T>` means "enough storage for a `T`
|
||||
// instance, and that they can manually control the lifetime of that instance
|
||||
// through the `.construct` and `.destroy` member functions.
|
||||
//
|
||||
// It is undefined behavior to:
|
||||
// * Call `construct` on an already-initialized instance.
|
||||
// * Call `destroy` on a non-initialized instance.
|
||||
// * Access the reference returned by `get` on a non-initialized instance.
|
||||
//
|
||||
template <typename T>
|
||||
union uninitialized
|
||||
{
|
||||
private:
|
||||
T d_datum;
|
||||
|
||||
public:
|
||||
using inner_type = T;
|
||||
|
||||
uninitialized() { }
|
||||
~uninitialized() { }
|
||||
|
||||
template <typename... Ts>
|
||||
void construct(Ts&&... xs)
|
||||
{
|
||||
new (&d_datum) T(std::forward<Ts>(xs)...);
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
d_datum.~T();
|
||||
}
|
||||
|
||||
T& get() { return d_datum; }
|
||||
const T& get() const { return d_datum; }
|
||||
};
|
||||
|
||||
// This class is not meant to be shown/completely understood from the students.
|
||||
//
|
||||
// It basically unwraps `uninitialized<T>` upon dereference, behaving as any
|
||||
// other normal random access iterator, transparently to the user.
|
||||
//
|
||||
template <typename T>
|
||||
class iter_impl
|
||||
{
|
||||
private:
|
||||
T* d_ptr;
|
||||
using inner_type = typename T::inner_type;
|
||||
|
||||
public:
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = inner_type;
|
||||
using pointer = inner_type*;
|
||||
using reference = inner_type&;
|
||||
using iterator_category = std::random_access_iterator_tag;
|
||||
|
||||
iter_impl() : d_ptr(nullptr) { }
|
||||
iter_impl(T* rhs) : d_ptr(rhs) { }
|
||||
|
||||
iter_impl(const iter_impl& rhs) : d_ptr(rhs.d_ptr) { }
|
||||
iter_impl& operator=(const iter_impl &rhs) { d_ptr = rhs.d_ptr; return *this; }
|
||||
|
||||
iter_impl& operator+=(difference_type rhs) { d_ptr += rhs; return *this; }
|
||||
iter_impl& operator-=(difference_type rhs) { d_ptr -= rhs; return *this; }
|
||||
|
||||
inner_type& operator*() const { return d_ptr->get(); }
|
||||
inner_type* operator->() const { return &d_ptr->get(); }
|
||||
inner_type& operator[](difference_type rhs) const { return d_ptr[rhs]; }
|
||||
|
||||
iter_impl& operator++() { ++d_ptr; return *this; }
|
||||
iter_impl& operator--() { --d_ptr; return *this; }
|
||||
|
||||
iter_impl operator++(int) { iter_impl tmp(*this); ++d_ptr; return tmp; }
|
||||
iter_impl operator--(int) { iter_impl tmp(*this); --d_ptr; return tmp; }
|
||||
|
||||
difference_type operator-(const iter_impl& rhs) const { return iter_impl(d_ptr - rhs.ptr); }
|
||||
|
||||
iter_impl operator+(difference_type rhs) const { return iter_impl(d_ptr + rhs); }
|
||||
iter_impl operator-(difference_type rhs) const { return iter_impl(d_ptr - rhs); }
|
||||
friend iter_impl operator+(difference_type lhs, const iter_impl& rhs) { return iter_impl(lhs + rhs.d_ptr); }
|
||||
friend iter_impl operator-(difference_type lhs, const iter_impl& rhs) { return iter_impl(lhs - rhs.d_ptr); }
|
||||
|
||||
bool operator==(const iter_impl& rhs) const { return d_ptr == rhs.d_ptr; }
|
||||
bool operator!=(const iter_impl& rhs) const { return d_ptr != rhs.d_ptr; }
|
||||
bool operator>(const iter_impl& rhs) const { return d_ptr > rhs.d_ptr; }
|
||||
bool operator<(const iter_impl& rhs) const { return d_ptr < rhs.d_ptr; }
|
||||
bool operator>=(const iter_impl& rhs) const { return d_ptr >= rhs.d_ptr; }
|
||||
bool operator<=(const iter_impl& rhs) const { return d_ptr <= rhs.d_ptr; }
|
||||
};
|
||||
|
||||
} // close namespace detail
|
||||
} // close namespace trnx
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user