Replace void* with iterator* in C# std::list wrappers
Better to use the actual type rather than void* in the implementaton. It also mean the %apply that was used in the implementation won't inadvertently affect users other use of void* types.
This commit is contained in:
parent
78051fdd33
commit
59030cb3d2
2 changed files with 46 additions and 37 deletions
|
|
@ -7,6 +7,19 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
Version 4.0.0 (in progress)
|
Version 4.0.0 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2019-03-25: Liryna
|
||||||
|
[C#] #1143 Add std_list.i for std::list support.
|
||||||
|
The C# std::list<T> wrappers are made to look and feel like a C#
|
||||||
|
System.Collections.Generic.LinkedList<> collection.
|
||||||
|
The IEnumerable<> interface is implemented in the proxy class.
|
||||||
|
The ICollection<> interface can also be implemented to provide enhanced functionality
|
||||||
|
whenever a C++ operator== is available. This is the case for when T is a
|
||||||
|
primitive type or a pointer. If T does define an operator==, then use the
|
||||||
|
SWIG_STD_LIST_ENHANCED macro to obtain this enhanced functionality, for example:
|
||||||
|
|
||||||
|
SWIG_STD_LIST_ENHANCED(SomeNamespace::Klass)
|
||||||
|
%template(ListKlass) std::list<SomeNamespace::Klass>;
|
||||||
|
|
||||||
2019-03-18: richardbeare
|
2019-03-18: richardbeare
|
||||||
[R] #1328 Non-trivial enums are working now. The enum values are now obtained from
|
[R] #1328 Non-trivial enums are working now. The enum values are now obtained from
|
||||||
the C/C++ layer. const reference enums and C++11 enum classes are also now working.
|
the C/C++ layer. const reference enums and C++11 enum classes are also now working.
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@
|
||||||
// MACRO for use within the std::list class body
|
// MACRO for use within the std::list class body
|
||||||
%define SWIG_STD_LIST_MINIMUM_INTERNAL(CSINTERFACE, CTYPE...)
|
%define SWIG_STD_LIST_MINIMUM_INTERNAL(CSINTERFACE, CTYPE...)
|
||||||
%typemap(csinterfaces) std::list< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n";
|
%typemap(csinterfaces) std::list< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n";
|
||||||
|
|
||||||
|
%apply void *VOID_INT_PTR { std::list< CTYPE >::iterator * };
|
||||||
|
|
||||||
%proxycode %{
|
%proxycode %{
|
||||||
public $csclassname(global::System.Collections.IEnumerable c) : this() {
|
public $csclassname(global::System.Collections.IEnumerable c) : this() {
|
||||||
if (c == null)
|
if (c == null)
|
||||||
|
|
@ -288,7 +291,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator== ($csclassnameNode node1, $csclassnameNode node2) {
|
public static bool operator==($csclassnameNode node1, $csclassnameNode node2) {
|
||||||
if (object.ReferenceEquals(node1, null) && object.ReferenceEquals(node2, null))
|
if (object.ReferenceEquals(node1, null) && object.ReferenceEquals(node2, null))
|
||||||
return true;
|
return true;
|
||||||
if (object.ReferenceEquals(node1, null) || object.ReferenceEquals(node2, null))
|
if (object.ReferenceEquals(node1, null) || object.ReferenceEquals(node2, null))
|
||||||
|
|
@ -296,7 +299,7 @@
|
||||||
return node1.Equals(node2);
|
return node1.Equals(node2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator!= ($csclassnameNode node1, $csclassnameNode node2) {
|
public static bool operator!=($csclassnameNode node1, $csclassnameNode node2) {
|
||||||
if (node1 == null && node2 == null)
|
if (node1 == null && node2 == null)
|
||||||
return false;
|
return false;
|
||||||
if (node1 == null || node2 == null)
|
if (node1 == null || node2 == null)
|
||||||
|
|
@ -344,6 +347,8 @@ public:
|
||||||
typedef value_type& reference;
|
typedef value_type& reference;
|
||||||
typedef const value_type& const_reference;
|
typedef const value_type& const_reference;
|
||||||
|
|
||||||
|
class iterator;
|
||||||
|
|
||||||
void push_front(CTYPE const& x);
|
void push_front(CTYPE const& x);
|
||||||
void push_back(CTYPE const& x);
|
void push_back(CTYPE const& x);
|
||||||
%rename(RemoveFirst) pop_front;
|
%rename(RemoveFirst) pop_front;
|
||||||
|
|
@ -354,69 +359,63 @@ public:
|
||||||
%rename(Clear) clear;
|
%rename(Clear) clear;
|
||||||
void clear();
|
void clear();
|
||||||
%extend {
|
%extend {
|
||||||
const_reference getItem(void *iter) {
|
const_reference getItem(iterator *iter) {
|
||||||
std::list< CTYPE >::iterator it = *reinterpret_cast<std::list< CTYPE >::iterator*>(iter);
|
return **iter;
|
||||||
return *it;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setItem(void *iter, CTYPE const& val) {
|
void setItem(iterator *iter, CTYPE const& val) {
|
||||||
std::list< CTYPE >::iterator* it = reinterpret_cast<std::list< CTYPE >::iterator*>(iter);
|
*(*iter) = val;
|
||||||
*(*it) = val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *getFirstIter() {
|
iterator *getFirstIter() {
|
||||||
if ($self->size() == 0)
|
if ($self->size() == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
std::list< CTYPE >::iterator* it = new std::list< CTYPE >::iterator($self->begin());
|
return new std::list< CTYPE >::iterator($self->begin());
|
||||||
return reinterpret_cast<void *>(it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *getLastIter() {
|
iterator *getLastIter() {
|
||||||
if ($self->size() == 0)
|
if ($self->size() == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
std::list< CTYPE >::iterator* it = new std::list< CTYPE >::iterator(--$self->end());
|
return new std::list< CTYPE >::iterator(--$self->end());
|
||||||
return reinterpret_cast<void *>(it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *getNextIter(void *iter) {
|
iterator *getNextIter(iterator *iter) {
|
||||||
std::list< CTYPE >::iterator it = *(reinterpret_cast<std::list< CTYPE >::iterator *>(iter));
|
std::list< CTYPE >::iterator it = *iter;
|
||||||
if (std::distance(it, --$self->end()) != 0) {
|
if (std::distance(it, --$self->end()) != 0) {
|
||||||
std::list< CTYPE >::iterator* itnext = new std::list< CTYPE >::iterator(++it);
|
std::list< CTYPE >::iterator* itnext = new std::list< CTYPE >::iterator(++it);
|
||||||
return reinterpret_cast<void *>(itnext);
|
return itnext;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *getPrevIter(void *iter) {
|
iterator *getPrevIter(iterator *iter) {
|
||||||
std::list< CTYPE >::iterator it = *(reinterpret_cast<std::list< CTYPE >::iterator *>(iter));
|
std::list< CTYPE >::iterator it = *iter;
|
||||||
if (std::distance($self->begin(), it) != 0) {
|
if (std::distance($self->begin(), it) != 0) {
|
||||||
std::list< CTYPE >::iterator* itprev = new std::list< CTYPE >::iterator(--it);
|
std::list< CTYPE >::iterator* itprev = new std::list< CTYPE >::iterator(--it);
|
||||||
return reinterpret_cast<void *>(itprev);
|
return itprev;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *insertNode(void *iter, CTYPE const& value) {
|
iterator *insertNode(iterator *iter, CTYPE const& value) {
|
||||||
std::list< CTYPE >::iterator it = $self->insert(*(reinterpret_cast<std::list< CTYPE >::iterator *>(iter)), value);
|
std::list< CTYPE >::iterator it = $self->insert(*iter, value);
|
||||||
void* newit = reinterpret_cast<void *>(new std::list< CTYPE >::iterator(it));
|
return new std::list< CTYPE >::iterator(it);
|
||||||
return newit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void eraseIter(void *iter) {
|
void eraseIter(iterator *iter) {
|
||||||
std::list< CTYPE >::iterator it = *reinterpret_cast<std::list< CTYPE >::iterator*>(iter);
|
std::list< CTYPE >::iterator it = *iter;
|
||||||
$self->erase(it);
|
$self->erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteIter(void *iter) {
|
void deleteIter(iterator *iter) {
|
||||||
std::list< CTYPE >::iterator* it = reinterpret_cast<std::list< CTYPE >::iterator*>(iter);
|
delete iter;
|
||||||
delete it;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equals(void *iter1, void *iter2) {
|
bool equals(iterator *iter1, iterator *iter2) {
|
||||||
if (iter1 == NULL && iter2 == NULL)
|
if (iter1 == NULL && iter2 == NULL)
|
||||||
return true;
|
return true;
|
||||||
std::list< CTYPE >::iterator it1 = *reinterpret_cast<std::list< CTYPE >::iterator*>(iter1);
|
std::list< CTYPE >::iterator it1 = *iter1;
|
||||||
std::list< CTYPE >::iterator it2 = *reinterpret_cast<std::list< CTYPE >::iterator*>(iter2);
|
std::list< CTYPE >::iterator it2 = *iter2;
|
||||||
return it1 == it2;
|
return it1 == it2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -439,10 +438,9 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *find(CTYPE const& value) {
|
iterator *find(CTYPE const& value) {
|
||||||
if (std::find($self->begin(), $self->end(), value) != $self->end()) {
|
if (std::find($self->begin(), $self->end(), value) != $self->end()) {
|
||||||
void* it = reinterpret_cast<void *>(new std::list< CTYPE >::iterator(std::find($self->begin(), $self->end(), value)));
|
return new std::list< CTYPE >::iterator(std::find($self->begin(), $self->end(), value));
|
||||||
return it;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -458,8 +456,6 @@ public:
|
||||||
%}
|
%}
|
||||||
%enddef
|
%enddef
|
||||||
|
|
||||||
%apply void *VOID_INT_PTR { void *iter1, void *iter2, void *iter, void *find, void *insertNode, void *getPrevIter, void *getNextIter, void *getFirstIter, void *getLastIter }
|
|
||||||
|
|
||||||
// Macros for std::list class specializations/enhancements
|
// Macros for std::list class specializations/enhancements
|
||||||
%define SWIG_STD_LIST_ENHANCED(CTYPE...)
|
%define SWIG_STD_LIST_ENHANCED(CTYPE...)
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue