Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Further work
Browse files Browse the repository at this point in the history
  • Loading branch information
TurkeyMan committed Aug 27, 2018
1 parent 585e8c4 commit fca0fb5
Show file tree
Hide file tree
Showing 7 changed files with 430 additions and 227 deletions.
54 changes: 53 additions & 1 deletion src/core/stdcpp/allocator.d
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,56 @@ extern(C++, std):
* Allocators are classes that define memory models to be used by some parts of
* the C++ Standard Library, and most specifically, by STL containers.
*/
extern(C++, class) struct allocator(T) { }
extern(C++, class) struct allocator(T)
{
static assert(!is(T == const), "The C++ Standard forbids containers of const elements because allocator!(const T) is ill-formed.");

alias value_type = T;

alias pointer = value_type*;
alias const_pointer = const value_type*;

alias reference = ref value_type;
alias const_reference = ref const(value_type);

alias size_type = size_t;
alias difference_type = ptrdiff_t;

extern(D) size_t max_size() const nothrow @safe @nogc { return size_t.max / T.sizeof; }

// these need to be defined locally to work on local types...
extern(D) void construct(Ty, Args...)(Ty* ptr, auto ref Args args)
{
// placement new...
assert(false, "TODO: can't use emplace, cus it's in phobos...");
}

extern(D) void destroy(Ty)(Ty* ptr)
{
import object : destroy;
ptr.destroy(); // TODO: use `destruct` instead of destroy, which should exist in the future...
}


// platform specific detail
version(CRuntime_Microsoft)
{
extern(D) void deallocate(pointer ptr, size_type count) nothrow @safe @nogc { _Deallocate(ptr, count, T.sizeof); }
extern(D) pointer allocate(size_type count) nothrow @trusted @nogc { return cast(pointer)_Allocate(count, T.sizeof); }
extern(D) pointer allocate(size_type count, const(void)*) nothrow @safe @nogc { return allocate(count); }
}
else
{
void deallocate(pointer ptr, size_type count) nothrow @trusted @nogc;
pointer allocate(size_type count) nothrow @trusted @nogc;
pointer allocate(size_type count, const(void)*) nothrow @trusted @nogc;
}
}


// platform detail
version(CRuntime_Microsoft)
{
void* _Allocate(size_t _Count, size_t _Sz, bool _Try_aligned_allocation = true) nothrow @trusted @nogc;
void _Deallocate(void* _Ptr, size_t _Count, size_t _Sz) nothrow @trusted @nogc;
}
108 changes: 33 additions & 75 deletions src/core/stdcpp/array.d
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@

module core.stdcpp.array;

///////////////////////////////////////////////////////////////////////////////
// std::array declaration.
//
// - no iterators
///////////////////////////////////////////////////////////////////////////////

import stdcpp.allocator;

alias array = std.array;

extern(C++, std):
Expand All @@ -32,74 +24,56 @@ extern(C++, class) struct array(T, size_t N)
alias const_reference = ref const(T);
alias pointer = T*;
alias const_pointer = const(T)*;
// alias iterator = pointer;
// alias const_iterator = const_pointer;
// alias reverse_iterator
// alias const_reverse_iterator

// Iterators
// iterator begin() @trusted @nogc;
// const_iterator begin() const @trusted @nogc;
// const_iterator cbegin() const @trusted @nogc;
// iterator end() @trusted @nogc;
// const_iterator end() const @trusted @nogc;
// const_iterator cend() const @trusted @nogc;

// no reverse iterator for now.

alias as_array this;
alias as_array this;

extern(D) size_type size() const nothrow @safe @nogc { return N; }
extern(D) size_type max_size() const nothrow @safe @nogc { return N; }
extern(D) bool empty() const nothrow @safe @nogc { return N > 0; }
extern(D) size_type size() const nothrow @safe @nogc { return N; }
extern(D) size_type max_size() const nothrow @safe @nogc { return N; }
extern(D) bool empty() const nothrow @safe @nogc { return N == 0; }

// Element access
extern(D) reference front() @safe @nogc { return as_array()[0]; }
extern(D) const_reference front() const @safe @nogc { return as_array()[0]; }
extern(D) reference back() @safe @nogc { return as_array()[N == 0 ? 0 : N-1]; }
extern(D) const_reference back() const @safe @nogc { return as_array()[N == 0 ? 0 : N-1]; }
extern(D) reference front() @safe @nogc { static if (N > 0) { return as_array()[0]; } else { return as_array()[][0]; } }
extern(D) const_reference front() const @safe @nogc { static if (N > 0) { return as_array()[0]; } else { return as_array()[][0]; } }
extern(D) reference back() @safe @nogc { static if (N > 0) { return as_array()[N-1]; } else { return as_array()[][0]; } }
extern(D) const_reference back() const @safe @nogc { static if (N > 0) { return as_array()[N-1]; } else { return as_array()[][0]; } }

extern(D) void fill(ref const(T) value) @safe @nogc { foreach (ref T v; as_array()) v = value; }
extern(D) void fill(ref const(T) value) @safe @nogc { foreach (ref T v; as_array()) v = value; }

// D helpers
extern(D) T[] opSlice() nothrow @safe @nogc { return as_array(); }
extern(D) const(T)[] opSlice() const nothrow @safe @nogc { return as_array(); }
extern(D) T[] opSlice(size_type start, size_type end) @safe { assert(start <= end && end <= N, "Index out of bounds"); return as_array()[start .. end]; }
extern(D) const(T)[] opSlice(size_type start, size_type end) const @safe { assert(start <= end && end <= N, "Index out of bounds"); return as_array()[start .. end]; }
extern(D) size_type opDollar(size_t pos)() const nothrow @safe @nogc { static assert(pos == 0, "std::vector is one-dimensional"); return N; }

// support all the assignment variants
extern(D) void opSliceAssign(T value) { opSlice()[] = value; }
extern(D) void opSliceAssign(T value, size_type i, size_type j) { opSlice(i, j)[] = value; }
extern(D) void opSliceUnary(string op)() if (op == "++" || op == "--") { mixin(op ~ "opSlice()[];"); }
extern(D) void opSliceUnary(string op)(size_type i, size_type j) if (op == "++" || op == "--") { mixin(op ~ "opSlice(i, j)[];"); }
extern(D) void opSliceOpAssign(string op)(T value) { mixin("opSlice()[] " ~ op ~ "= value;"); }
extern(D) void opSliceOpAssign(string op)(T value, size_type i, size_type j) { mixin("opSlice(i, j)[] " ~ op ~ "= value;"); }

private:
extern(D) size_type opDollar(size_t pos)() const nothrow @safe @nogc { static assert(pos == 0, "std::vector is one-dimensional"); return N; }

version(CRuntime_Microsoft)
{
import core.stdcpp.utility : _Xout_of_range;
// perf will be greatly improved by inlining the primitive access functions
extern(D) T* data() nothrow @safe @nogc { return &_Elems[0]; }
extern(D) const(T)* data() const nothrow @safe @nogc { return &_Elems[0]; }

T[N ? N : 1] _Elems;
extern(D) ref T at(size_type i) nothrow @trusted @nogc { static if (N > 0) { if (N <= i) _Xran(); return _Elems.ptr[i]; } else { _Xran(); return _Elems[0]; } }
extern(D) ref const(T) at(size_type i) const nothrow @trusted @nogc { static if (N > 0) { if (N <= i) _Xran(); return _Elems.ptr[i]; } else { _Xran(); return _Elems[0]; } }

void _Xran() const @trusted @nogc { _Xout_of_range("invalid array<T, N> subscript"); }
extern(D) ref inout(T)[N] as_array() const inout @safe @nogc { return _Elems[0 .. N]; }

public:
// perf will be greatly improved by inlining the primitive access functions
extern(D) T* data() nothrow @safe @nogc { return &_Elems[0]; }
extern(D) const(T)* data() const nothrow @safe @nogc { return &_Elems[0]; }
private:
import core.stdcpp.utility : _Xout_of_range;

extern(D) ref T opIndex(size_type i) nothrow @safe @nogc { return _Elems[0 .. N][i]; }
extern(D) ref const(T) opIndex(size_type i) const nothrow @safe @nogc { return _Elems[0 .. N][i]; }
extern(D) ref T at(size_type i) nothrow @trusted @nogc { static if (N > 0) { if (N <= i) _Xran(); return _Elems.ptr[i]; } else { _Xran(); } }
extern(D) ref const(T) at(size_type i) const nothrow @trusted @nogc { static if (N > 0) { if (N <= i) _Xran(); return _Elems.ptr[i]; } else { _Xran(); } }
T[N ? N : 1] _Elems;

extern(D) T[] as_array() nothrow @safe @nogc { return _Elems[0 .. N]; }
extern(D) const(T)[] as_array() const nothrow @safe @nogc { return _Elems[0 .. N]; }
void _Xran() const @safe @nogc { _Xout_of_range("invalid array<T, N> subscript"); }
}
else version(CRuntime_Glibc)
{
import core.exception : RangeError;

// perf will be greatly improved by inlining the primitive access functions
extern(D) T* data() nothrow @safe @nogc { static if (N > 0) { return &_M_elems[0]; } else { return null; } }
extern(D) const(T)* data() const nothrow @safe @nogc { static if (N > 0) { return &_M_elems[0]; } else { return null; } }

extern(D) ref T at(size_type i) @trusted { if (i >= N) throw new RangeError("Index out of range"); return _M_elems.ptr[i]; }
extern(D) ref const(T) at(size_type i) const @trusted { if (i >= N) throw new RangeError("Index out of range"); return _M_elems.ptr[i]; }

extern(D) ref inout(T)[N] as_array() inout nothrow @safe @nogc { return _M_elems[0 .. N]; }

private:
static if (N > 0)
{
T[N] _M_elems;
Expand All @@ -109,22 +83,6 @@ private:
struct _Placeholder {}
_Placeholder _M_placeholder;
}

public:
import core.exception : RangeError;

// perf will be greatly improved by inlining the primitive access functions
extern(D) T* data() nothrow @safe @nogc { static if (N > 0) { return &_M_elems[0]; } else { return null; } }
extern(D) const(T)* data() const nothrow @safe @nogc { static if (N > 0) { return &_M_elems[0]; } else { return null; } }

extern(D) ref T opIndex(size_type i) nothrow @nogc { static if (N > 0) { return _M_elems[i]; } else { return (cast(T[])null)[i]; } }
extern(D) ref const(T) opIndex(size_type i) const nothrow @nogc { static if (N > 0) { return _M_elems[i]; } else { return (cast(T[])null)[i]; } }
extern(D) ref T at(size_type i) @trusted { if (i >= N) throw new RangeError("Index out of range"); return _M_elems.ptr[i]; }
extern(D) ref const(T) at(size_type i) const @trusted { if (i >= N) throw new RangeError("Index out of range"); return _M_elems.ptr[i]; }

alias as_array this;
extern(D) T[] as_array() nothrow @safe @nogc { static if (N > 0) { return _M_elems[]; } else { return null; } }
extern(D) const(T)[] as_array() const nothrow @safe @nogc { static if (N > 0) { return _M_elems[]; } else { return null; } }
}
else
{
Expand Down
Loading

0 comments on commit fca0fb5

Please sign in to comment.