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

Commit fca0fb5

Browse files
committed
Further work
1 parent 585e8c4 commit fca0fb5

File tree

7 files changed

+430
-227
lines changed

7 files changed

+430
-227
lines changed

src/core/stdcpp/allocator.d

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,56 @@ extern(C++, std):
2020
* Allocators are classes that define memory models to be used by some parts of
2121
* the C++ Standard Library, and most specifically, by STL containers.
2222
*/
23-
extern(C++, class) struct allocator(T) { }
23+
extern(C++, class) struct allocator(T)
24+
{
25+
static assert(!is(T == const), "The C++ Standard forbids containers of const elements because allocator!(const T) is ill-formed.");
26+
27+
alias value_type = T;
28+
29+
alias pointer = value_type*;
30+
alias const_pointer = const value_type*;
31+
32+
alias reference = ref value_type;
33+
alias const_reference = ref const(value_type);
34+
35+
alias size_type = size_t;
36+
alias difference_type = ptrdiff_t;
37+
38+
extern(D) size_t max_size() const nothrow @safe @nogc { return size_t.max / T.sizeof; }
39+
40+
// these need to be defined locally to work on local types...
41+
extern(D) void construct(Ty, Args...)(Ty* ptr, auto ref Args args)
42+
{
43+
// placement new...
44+
assert(false, "TODO: can't use emplace, cus it's in phobos...");
45+
}
46+
47+
extern(D) void destroy(Ty)(Ty* ptr)
48+
{
49+
import object : destroy;
50+
ptr.destroy(); // TODO: use `destruct` instead of destroy, which should exist in the future...
51+
}
52+
53+
54+
// platform specific detail
55+
version(CRuntime_Microsoft)
56+
{
57+
extern(D) void deallocate(pointer ptr, size_type count) nothrow @safe @nogc { _Deallocate(ptr, count, T.sizeof); }
58+
extern(D) pointer allocate(size_type count) nothrow @trusted @nogc { return cast(pointer)_Allocate(count, T.sizeof); }
59+
extern(D) pointer allocate(size_type count, const(void)*) nothrow @safe @nogc { return allocate(count); }
60+
}
61+
else
62+
{
63+
void deallocate(pointer ptr, size_type count) nothrow @trusted @nogc;
64+
pointer allocate(size_type count) nothrow @trusted @nogc;
65+
pointer allocate(size_type count, const(void)*) nothrow @trusted @nogc;
66+
}
67+
}
68+
69+
70+
// platform detail
71+
version(CRuntime_Microsoft)
72+
{
73+
void* _Allocate(size_t _Count, size_t _Sz, bool _Try_aligned_allocation = true) nothrow @trusted @nogc;
74+
void _Deallocate(void* _Ptr, size_t _Count, size_t _Sz) nothrow @trusted @nogc;
75+
}

src/core/stdcpp/array.d

Lines changed: 33 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,6 @@
1111

1212
module core.stdcpp.array;
1313

14-
///////////////////////////////////////////////////////////////////////////////
15-
// std::array declaration.
16-
//
17-
// - no iterators
18-
///////////////////////////////////////////////////////////////////////////////
19-
20-
import stdcpp.allocator;
21-
2214
alias array = std.array;
2315

2416
extern(C++, std):
@@ -32,74 +24,56 @@ extern(C++, class) struct array(T, size_t N)
3224
alias const_reference = ref const(T);
3325
alias pointer = T*;
3426
alias const_pointer = const(T)*;
35-
// alias iterator = pointer;
36-
// alias const_iterator = const_pointer;
37-
// alias reverse_iterator
38-
// alias const_reverse_iterator
39-
40-
// Iterators
41-
// iterator begin() @trusted @nogc;
42-
// const_iterator begin() const @trusted @nogc;
43-
// const_iterator cbegin() const @trusted @nogc;
44-
// iterator end() @trusted @nogc;
45-
// const_iterator end() const @trusted @nogc;
46-
// const_iterator cend() const @trusted @nogc;
47-
48-
// no reverse iterator for now.
4927

50-
alias as_array this;
28+
alias as_array this;
5129

52-
extern(D) size_type size() const nothrow @safe @nogc { return N; }
53-
extern(D) size_type max_size() const nothrow @safe @nogc { return N; }
54-
extern(D) bool empty() const nothrow @safe @nogc { return N > 0; }
30+
extern(D) size_type size() const nothrow @safe @nogc { return N; }
31+
extern(D) size_type max_size() const nothrow @safe @nogc { return N; }
32+
extern(D) bool empty() const nothrow @safe @nogc { return N == 0; }
5533

5634
// Element access
57-
extern(D) reference front() @safe @nogc { return as_array()[0]; }
58-
extern(D) const_reference front() const @safe @nogc { return as_array()[0]; }
59-
extern(D) reference back() @safe @nogc { return as_array()[N == 0 ? 0 : N-1]; }
60-
extern(D) const_reference back() const @safe @nogc { return as_array()[N == 0 ? 0 : N-1]; }
35+
extern(D) reference front() @safe @nogc { static if (N > 0) { return as_array()[0]; } else { return as_array()[][0]; } }
36+
extern(D) const_reference front() const @safe @nogc { static if (N > 0) { return as_array()[0]; } else { return as_array()[][0]; } }
37+
extern(D) reference back() @safe @nogc { static if (N > 0) { return as_array()[N-1]; } else { return as_array()[][0]; } }
38+
extern(D) const_reference back() const @safe @nogc { static if (N > 0) { return as_array()[N-1]; } else { return as_array()[][0]; } }
6139

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

6442
// D helpers
65-
extern(D) T[] opSlice() nothrow @safe @nogc { return as_array(); }
66-
extern(D) const(T)[] opSlice() const nothrow @safe @nogc { return as_array(); }
67-
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]; }
68-
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]; }
69-
extern(D) size_type opDollar(size_t pos)() const nothrow @safe @nogc { static assert(pos == 0, "std::vector is one-dimensional"); return N; }
70-
71-
// support all the assignment variants
72-
extern(D) void opSliceAssign(T value) { opSlice()[] = value; }
73-
extern(D) void opSliceAssign(T value, size_type i, size_type j) { opSlice(i, j)[] = value; }
74-
extern(D) void opSliceUnary(string op)() if (op == "++" || op == "--") { mixin(op ~ "opSlice()[];"); }
75-
extern(D) void opSliceUnary(string op)(size_type i, size_type j) if (op == "++" || op == "--") { mixin(op ~ "opSlice(i, j)[];"); }
76-
extern(D) void opSliceOpAssign(string op)(T value) { mixin("opSlice()[] " ~ op ~ "= value;"); }
77-
extern(D) void opSliceOpAssign(string op)(T value, size_type i, size_type j) { mixin("opSlice(i, j)[] " ~ op ~ "= value;"); }
78-
79-
private:
43+
extern(D) size_type opDollar(size_t pos)() const nothrow @safe @nogc { static assert(pos == 0, "std::vector is one-dimensional"); return N; }
44+
8045
version(CRuntime_Microsoft)
8146
{
82-
import core.stdcpp.utility : _Xout_of_range;
47+
// perf will be greatly improved by inlining the primitive access functions
48+
extern(D) T* data() nothrow @safe @nogc { return &_Elems[0]; }
49+
extern(D) const(T)* data() const nothrow @safe @nogc { return &_Elems[0]; }
8350

84-
T[N ? N : 1] _Elems;
51+
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]; } }
52+
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]; } }
8553

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

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

93-
extern(D) ref T opIndex(size_type i) nothrow @safe @nogc { return _Elems[0 .. N][i]; }
94-
extern(D) ref const(T) opIndex(size_type i) const nothrow @safe @nogc { return _Elems[0 .. N][i]; }
95-
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(); } }
96-
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(); } }
59+
T[N ? N : 1] _Elems;
9760

98-
extern(D) T[] as_array() nothrow @safe @nogc { return _Elems[0 .. N]; }
99-
extern(D) const(T)[] as_array() const nothrow @safe @nogc { return _Elems[0 .. N]; }
61+
void _Xran() const @safe @nogc { _Xout_of_range("invalid array<T, N> subscript"); }
10062
}
10163
else version(CRuntime_Glibc)
10264
{
65+
import core.exception : RangeError;
66+
67+
// perf will be greatly improved by inlining the primitive access functions
68+
extern(D) T* data() nothrow @safe @nogc { static if (N > 0) { return &_M_elems[0]; } else { return null; } }
69+
extern(D) const(T)* data() const nothrow @safe @nogc { static if (N > 0) { return &_M_elems[0]; } else { return null; } }
70+
71+
extern(D) ref T at(size_type i) @trusted { if (i >= N) throw new RangeError("Index out of range"); return _M_elems.ptr[i]; }
72+
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]; }
73+
74+
extern(D) ref inout(T)[N] as_array() inout nothrow @safe @nogc { return _M_elems[0 .. N]; }
75+
76+
private:
10377
static if (N > 0)
10478
{
10579
T[N] _M_elems;
@@ -109,22 +83,6 @@ private:
10983
struct _Placeholder {}
11084
_Placeholder _M_placeholder;
11185
}
112-
113-
public:
114-
import core.exception : RangeError;
115-
116-
// perf will be greatly improved by inlining the primitive access functions
117-
extern(D) T* data() nothrow @safe @nogc { static if (N > 0) { return &_M_elems[0]; } else { return null; } }
118-
extern(D) const(T)* data() const nothrow @safe @nogc { static if (N > 0) { return &_M_elems[0]; } else { return null; } }
119-
120-
extern(D) ref T opIndex(size_type i) nothrow @nogc { static if (N > 0) { return _M_elems[i]; } else { return (cast(T[])null)[i]; } }
121-
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]; } }
122-
extern(D) ref T at(size_type i) @trusted { if (i >= N) throw new RangeError("Index out of range"); return _M_elems.ptr[i]; }
123-
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]; }
124-
125-
alias as_array this;
126-
extern(D) T[] as_array() nothrow @safe @nogc { static if (N > 0) { return _M_elems[]; } else { return null; } }
127-
extern(D) const(T)[] as_array() const nothrow @safe @nogc { static if (N > 0) { return _M_elems[]; } else { return null; } }
12886
}
12987
else
13088
{

0 commit comments

Comments
 (0)