Skip to content

Commit

Permalink
Add support for vector and list on POSIX
Browse files Browse the repository at this point in the history
This adds support and test for C++'s `<vector>` and `<list>` headers
on POSIX (Linux / Mac OS) platforms.
  • Loading branch information
Emmankoko authored and Geod24 committed Feb 5, 2024
1 parent a819d41 commit 635f7cc
Show file tree
Hide file tree
Showing 10 changed files with 551 additions and 32 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ jobs:
dc:
- ldc-latest
target:
- { name: g++-9, compiler: g++, cxx-version: 9.4.0 }
# - { name: g++-9, compiler: g++, cxx-version: 9.4.0 }
- { name: clang-13, compiler: clang, cxx-version: 13.0.0 }

# Using a specific version for reproductibility.
# Feel free to update when a new release has matured.
Expand Down
15 changes: 15 additions & 0 deletions dub.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@
},
{
"name": "unittest",
"lflags": [ "-lstdc++" ],
"preGenerateCommands": [
"clang++ -c extras/vector.cpp -o extras/vector.o",
"clang++ -c extras/list.cpp -o extras/list.o"
],
"sourceFiles": [ "extras/*.o" ]
},
{
"name": "unittest-gcc",
"lflags": [ "-lc++" ],
"preGenerateCommands": [
"g++ -c extras/vector.cpp -o extras/vector.o",
"g++ -c extras/list.cpp -o extras/list.o"
],
"sourceFiles": [ "extras/*.o" ]
}
]
}
3 changes: 3 additions & 0 deletions extras/list.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include <list>

template class std::list<int>;
3 changes: 3 additions & 0 deletions extras/vector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include <vector>

template class std::vector<int>;
293 changes: 293 additions & 0 deletions source/stdcpp/list.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
/**
* D bindings for std::list
*
* Copyright: Copyright (c) 2023 D Language Foundation
* License: Distributed under the
* $(LINK2 http://www.boost.org/LICENSE_1.0.txt, Boost Software License 1.0).
* (See accompanying file License)
* Authors: Emmanuel Nyarko, Mathias Lang
*/
module stdcpp.list;

import stdcpp.allocator;

version (CppRuntime_Gcc)
{
version (GLIBCXX_USE_CXX98_ABI)
{
private enum listNamespace = "std";
}
else
{
import core.internal.traits : AliasSeq;
private enum listNamespace = AliasSeq!("std", "__cxx11");
}
}
else
{
import stdcpp.xutility : StdNamespace;
alias listNamespace = StdNamespace;
}

enum def {value}; //for later use
extern(C++, (listNamespace)):

alias list(Type) = list!(Type, allocator!Type);

extern(C++, class) struct list(Type, Allocator)
{
static assert(!is(Type == bool), " list not required to have specialization for bool");

///
alias value_type = Type;

///
alias allocator_type = Allocator;

///
alias size_type = size_t;

///
alias pointer = Type*;

///
alias const_pointer = const(Type)*;

///
alias difference_type = ptrdiff_t;

///
ref list opAssign();

///
@disable this() @safe pure nothrow @nogc scope;

version (CppRuntime_Gcc)
{
version (GLIBCXX_USE_CXX98_ABI)
{
//allocator ctor
this(ref const allocator!Type);

//list(n,value) ctor until c++11
this(size_type __n, ref const value_type value, ref const allocator!Type);

/// Copy constructor
this(ref const list!Type __x);

extern(D) this(size_type n)
{
value_type type_instance = value_type.init;
allocator!Type alloc_instance = allocator!(Type).init;
this(n, type_instance, alloc_instance);
}

extern(D) void assign(size_type n, const value_type item)
{
this.assign(n, item);
}

extern(D) void push_back(const Type item)
{
this.push_back(item);
}

extern(D) void push_front(const Type item)
{
this.push_front(item);
}

extern(D) void remove(const value_type item)
{
this.remove(item);
}

void assign(size_type count, ref const value_type value);

ref list opAssign(ref const list!Type other);

//just const until c++11
allocator_type get_allocator() const;

ref value_type front();

// const(value_type) ref front() const;

ref value_type back();

pointer begin();

pointer end();

//just const until c++11
bool empty() const;

size_type size() const;

size_type max_size() const nothrow;

void clear();

//insert halted for now

void push_back(ref const Type val);

void pop_back();

void push_front(ref const value_type val);

void pop_front();

void swap(ref const list!Type other);

void merge( ref const list!Type other);

void merge(U)(ref const list!Type other, U comp);

void remove(const ref value_type val);

void reverse();

void sort();

size_type unique();

void sort(U)(U comp);

private struct node
{
node* prev;
node* next;
}
// pre-c++11 doesn't keep track of its size
private node A;
}
else // !GLIBCXX_USE_CXX98_ABI
{
this(def)
{
allocator!Type alloc_instance = allocator!(Type).init;
this(alloc_instance);
}

//allocator ctor
this(ref const allocator!Type);

// Copy constructor
this(ref const list!Type __x);

//list(n,value) ctor
this(size_type __n, ref const value_type value, ref const allocator!Type);

extern(D) this(size_type n, const value_type element)
{
allocator!Type alloc_instance = allocator!(Type).init;
this(n, element, alloc_instance);
}

this(ref const list!Type other, ref const allocator!Type);

//list(n) ctor
this(size_type __n, ref const allocator!Type);

extern(D) this(size_type n)
{
allocator!Type alloc_instance = allocator!(Type).init;
this(n, alloc_instance);
}

extern(D) void assign(size_type n, const value_type item)
{
this.assign(n, item);
}

extern(D) void push_back(const Type item)
{
this.push_back(item);
}

extern(D) void push_front(const Type item)
{
this.push_front(item);
}

extern(D) void resize(size_type n, const value_type item)
{
this.resize(n, item);
}

extern(D) void remove(const value_type item)
{
this.remove(item);
}

ref list opAssign(ref const list!Type other);

void assign(size_type count, ref const value_type value);

//const nothrow since C++11
allocator_type get_allocator() const nothrow;

ref value_type front();

ref value_type back();

pointer begin() nothrow;

pointer end() nothrow;

//const nothrow since c++11
bool empty() const nothrow;

size_type size() const nothrow;

void clear() nothrow;

void push_back(ref const Type val);

void pop_back();

void push_front(ref const value_type val);

void pop_front();

void resize(size_type count);

void resize(size_type count, ref const value_type val);

void swap(ref const list!Type other) nothrow;

void merge( ref const list!Type other);

void merge(U)(ref const list!Type other, U comp);

void remove(const ref value_type val);

void reverse() nothrow;

void sort();

void sort(U)(U comp);

void unique();

void unique(U)(U p);

size_type unique();

size_type unique(U)(U p);

private struct node
{
node* prev;
node* next;
}
private node A;
private size_type _M_size; //new list keeps track of it's size
}
}
else version (CppRuntime_Microsft)
{
static assert(0, "Not yet supported!");
}
}
20 changes: 15 additions & 5 deletions source/stdcpp/string.d
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,22 @@ extern(C++, (StdNamespace)) struct char_traits(CharT)
}
}

// I don't think we can have these here, otherwise symbols are emit to druntime, and we don't want that...
//alias std_string = basic_string!char;
/**
* An alias for `std::string`
*
* See_Also: https://cplusplus.com/reference/string/string/
*/
alias std_string = basic_string!char;

//alias std_u16string = basic_string!wchar; // TODO: can't mangle these yet either...
//alias std_u32string = basic_string!dchar;

/**
* An alias for `std::u32string`
*
* See_Also: https://cplusplus.com/reference/string/u32string/
*/
alias std_u32string = basic_string!dchar;

//alias std_wstring = basic_string!wchar_t; // TODO: we can't mangle wchar_t properly (yet?)

/**
Expand Down Expand Up @@ -1406,8 +1418,6 @@ extern(D):
}
else
{
pragma(msg, "libstdc++ std::__cxx11::basic_string is not yet supported; the struct contains an interior pointer which breaks D move semantics!");

//----------------------------------------------------------------------------------
// GCC/libstdc++ modern implementation
//----------------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit 635f7cc

Please sign in to comment.