From 9cb90982ee98b437fd3fe9f1257b48b5eef9b335 Mon Sep 17 00:00:00 2001 From: Takashi Tamura Date: Thu, 26 Jan 2017 11:42:07 +0900 Subject: [PATCH 1/8] fix Lib/std/std unordered containers --- Lib/std/std_container.i | 10 ++++------ Lib/std/std_unordered_map.i | 21 +++++++++------------ Lib/std/std_unordered_multimap.i | 21 ++++++++++----------- Lib/std/std_unordered_multiset.i | 15 +++++++-------- Lib/std/std_unordered_set.i | 2 -- 5 files changed, 30 insertions(+), 39 deletions(-) diff --git a/Lib/std/std_container.i b/Lib/std/std_container.i index 000163f1e..5d0f1f545 100644 --- a/Lib/std/std_container.i +++ b/Lib/std/std_container.i @@ -26,19 +26,17 @@ class const_iterator; iterator begin(); iterator end(); - #endif -%enddef - -%define %std_container_methods_reverse_iterators(container...) - - #ifdef SWIG_EXPORT_ITERATOR_METHODS + #if !defined(SWIG_NO_REVERSE_ITERATOR_METHODS) class reverse_iterator; class const_reverse_iterator; reverse_iterator rbegin(); reverse_iterator rend(); #endif + #endif + + %enddef // Common container methods diff --git a/Lib/std/std_unordered_map.i b/Lib/std/std_unordered_map.i index 1cb714821..4795120d1 100644 --- a/Lib/std/std_unordered_map.i +++ b/Lib/std/std_unordered_map.i @@ -4,7 +4,7 @@ // operator--() and constructor(compare function) not available for unordered_ // types // - +#define SWIG_NO_REVERSE_ITERATOR_METHODS %include %include @@ -22,8 +22,6 @@ } iterator find(const key_type& x); - iterator lower_bound(const key_type& x); - iterator upper_bound(const key_type& x); #endif %enddef @@ -68,7 +66,7 @@ namespace std { - template, + template, class _Pred = std::equal_to< _Key >, class _Alloc = allocator > > class unordered_map { public: @@ -101,29 +99,28 @@ namespace std { } } - %fragment(SWIG_Traits_frag(std::unordered_map< _Key, _Tp, _Compare, _Alloc >), "header", + %fragment(SWIG_Traits_frag(std::unordered_map< _Key, _Tp, _Hash, _Pred, _Alloc >), "header", fragment=SWIG_Traits_frag(std::pair< _Key, _Tp >), - fragment="StdMapTraits") { + fragment="StdUnorderedMapTraits") { namespace swig { - template <> struct traits > { + template <> struct traits > { typedef pointer_category category; static const char* type_name() { - return "std::unordered_map<" #_Key "," #_Tp "," #_Compare "," #_Alloc " >"; + return "std::unordered_map<" #_Key "," #_Tp "," #_Hash "," #_Pred "," #_Alloc " >"; } }; } } - %typemap_traits_ptr(SWIG_TYPECHECK_MAP, std::unordered_map< _Key, _Tp, _Compare, _Alloc >); - - unordered_map( const _Compare& ); + %typemap_traits_ptr(SWIG_TYPECHECK_MAP, std::unordered_map< _Key, _Tp, _Hash, _Pred, _Alloc >); #ifdef %swig_unordered_map_methods // Add swig/language extra methods - %swig_unordered_map_methods(std::unordered_map< _Key, _Tp, _Compare, _Alloc >); + %swig_unordered_map_methods(std::unordered_map< _Key, _Tp, _Hash, _Pred, _Alloc >); #endif %std_unordered_map_methods(unordered_map); }; } +#undef SWIG_NO_REVERSE_ITERATOR_METHODS diff --git a/Lib/std/std_unordered_multimap.i b/Lib/std/std_unordered_multimap.i index 46b56d88a..8feab03a4 100644 --- a/Lib/std/std_unordered_multimap.i +++ b/Lib/std/std_unordered_multimap.i @@ -6,10 +6,10 @@ // %include - +#define SWIG_NO_REVERSE_ITERATOR_METHODS %define %std_unordered_multimap_methods(mmap...) - %std_map_methods_common(mmap); + %std_unordered_map_methods_common(mmap); #ifdef SWIG_EXPORT_ITERATOR_METHODS std::pair equal_range(const key_type& x); @@ -44,7 +44,7 @@ namespace std { - template, + template, class _Pred = std::equal_to< _Key >, class _Alloc = allocator > > class unordered_multimap { public: @@ -63,28 +63,27 @@ namespace std { %traits_swigtype(_Key); %traits_swigtype(_Tp); - %fragment(SWIG_Traits_frag(std::unordered_multimap< _Key, _Tp, _Compare, _Alloc >), "header", + %fragment(SWIG_Traits_frag(std::unordered_multimap< _Key, _Tp, _Hash, _Pred, _Alloc >), "header", fragment=SWIG_Traits_frag(std::pair< _Key, _Tp >), - fragment="StdMultimapTraits") { + fragment="StdUnorderedMultimapTraits") { namespace swig { - template <> struct traits > { + template <> struct traits > { typedef pointer_category category; static const char* type_name() { - return "std::unordered_multimap<" #_Key "," #_Tp "," #_Compare "," #_Alloc " >"; + return "std::unordered_multimap<" #_Key "," #_Tp "," #_Hash "," #_Pred "," #_Alloc " >"; } }; } } - %typemap_traits_ptr(SWIG_TYPECHECK_MULTIMAP, std::unordered_multimap< _Key, _Tp, _Compare, _Alloc >); + %typemap_traits_ptr(SWIG_TYPECHECK_MULTIMAP, std::unordered_multimap< _Key, _Tp, _Hash, _Pred, _Alloc >); - unordered_multimap( const _Compare& ); - #ifdef %swig_unordered_multimap_methods // Add swig/language extra methods - %swig_unordered_multimap_methods(std::unordered_multimap< _Key, _Tp, _Compare, _Alloc >); + %swig_unordered_multimap_methods(std::unordered_multimap< _Key, _Tp, _Hash, _Pred, _Alloc >); #endif %std_unordered_multimap_methods(unordered_multimap); }; } +#undef SWIG_NO_REVERSE_ITERATOR_METHODS diff --git a/Lib/std/std_unordered_multiset.i b/Lib/std/std_unordered_multiset.i index 725ca2fe7..c0ada7e71 100644 --- a/Lib/std/std_unordered_multiset.i +++ b/Lib/std/std_unordered_multiset.i @@ -43,7 +43,8 @@ namespace std { //unordered_multiset - template , + template , + class _Compare = std::equal_to< _Key >, class _Alloc = allocator< _Key > > class unordered_multiset { public: @@ -59,26 +60,24 @@ namespace std { %traits_swigtype(_Key); - %fragment(SWIG_Traits_frag(std::unordered_multiset< _Key, _Compare, _Alloc >), "header", + %fragment(SWIG_Traits_frag(std::unordered_multiset< _Key, _Hash, _Compare, _Alloc >), "header", fragment=SWIG_Traits_frag(_Key), fragment="StdMultisetTraits") { namespace swig { - template <> struct traits > { + template <> struct traits > { typedef pointer_category category; static const char* type_name() { - return "std::unordered_multiset<" #_Key "," #_Compare "," #_Alloc " >"; + return "std::unordered_multiset<" #_Key "," #_Hash "," #_Compare "," #_Alloc " >"; } }; } } - %typemap_traits_ptr(SWIG_TYPECHECK_MULTISET, std::unordered_multiset< _Key, _Compare, _Alloc >); - - unordered_multiset( const _Compare& ); + %typemap_traits_ptr(SWIG_TYPECHECK_MULTISET, std::unordered_multiset< _Key, _Hash, _Compare, _Alloc >); #ifdef %swig_unordered_multiset_methods // Add swig/language extra methods - %swig_unordered_multiset_methods(std::unordered_multiset< _Key, _Compare, _Alloc >); + %swig_unordered_multiset_methods(std::unordered_multiset< _Key, _Hash, _Compare, _Alloc >); #endif %std_unordered_multiset_methods(unordered_multiset); diff --git a/Lib/std/std_unordered_set.i b/Lib/std/std_unordered_set.i index 98e792040..fb4415e1a 100644 --- a/Lib/std/std_unordered_set.i +++ b/Lib/std/std_unordered_set.i @@ -110,8 +110,6 @@ namespace std { %typemap_traits_ptr(SWIG_TYPECHECK_SET, std::unordered_set< _Key, _Hash, _Compare, _Alloc >); - unordered_set( const _Compare& ); - #ifdef %swig_unordered_set_methods // Add swig/language extra methods %swig_unordered_set_methods(std::unordered_set< _Key, _Hash, _Compare, _Alloc >); From 88a76de9fe3f80331af84ee9d00cf6649b1fbdf3 Mon Sep 17 00:00:00 2001 From: Takashi Tamura Date: Sun, 29 Jan 2017 09:47:18 +0900 Subject: [PATCH 2/8] use %std_container_methods_without_reverse_iterators --- Lib/std/std_container.i | 10 ++++++---- Lib/std/std_unordered_map.i | 4 +--- Lib/std/std_unordered_multimap.i | 2 -- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Lib/std/std_container.i b/Lib/std/std_container.i index 5d0f1f545..000163f1e 100644 --- a/Lib/std/std_container.i +++ b/Lib/std/std_container.i @@ -26,17 +26,19 @@ class const_iterator; iterator begin(); iterator end(); + #endif - #if !defined(SWIG_NO_REVERSE_ITERATOR_METHODS) +%enddef + +%define %std_container_methods_reverse_iterators(container...) + + #ifdef SWIG_EXPORT_ITERATOR_METHODS class reverse_iterator; class const_reverse_iterator; reverse_iterator rbegin(); reverse_iterator rend(); #endif - #endif - - %enddef // Common container methods diff --git a/Lib/std/std_unordered_map.i b/Lib/std/std_unordered_map.i index 4795120d1..9212eab46 100644 --- a/Lib/std/std_unordered_map.i +++ b/Lib/std/std_unordered_map.i @@ -4,12 +4,11 @@ // operator--() and constructor(compare function) not available for unordered_ // types // -#define SWIG_NO_REVERSE_ITERATOR_METHODS %include %include %define %std_unordered_map_methods_common(unordered_map...) - %std_container_methods(unordered_map); + %std_container_methods_without_reverse_iterators(unordered_map); size_type erase(const key_type& x); size_type count(const key_type& x) const; @@ -123,4 +122,3 @@ namespace std { }; } -#undef SWIG_NO_REVERSE_ITERATOR_METHODS diff --git a/Lib/std/std_unordered_multimap.i b/Lib/std/std_unordered_multimap.i index 8feab03a4..41520d42d 100644 --- a/Lib/std/std_unordered_multimap.i +++ b/Lib/std/std_unordered_multimap.i @@ -6,7 +6,6 @@ // %include -#define SWIG_NO_REVERSE_ITERATOR_METHODS %define %std_unordered_multimap_methods(mmap...) %std_unordered_map_methods_common(mmap); @@ -86,4 +85,3 @@ namespace std { %std_unordered_multimap_methods(unordered_multimap); }; } -#undef SWIG_NO_REVERSE_ITERATOR_METHODS From b8cf6412e885230d81c23279ca7a154814f57b75 Mon Sep 17 00:00:00 2001 From: Takashi Tamura Date: Sun, 29 Jan 2017 10:56:36 +0900 Subject: [PATCH 3/8] fix a %fragment argument. --- Lib/std/std_unordered_multiset.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/std/std_unordered_multiset.i b/Lib/std/std_unordered_multiset.i index c0ada7e71..50acb9dd7 100644 --- a/Lib/std/std_unordered_multiset.i +++ b/Lib/std/std_unordered_multiset.i @@ -62,7 +62,7 @@ namespace std { %fragment(SWIG_Traits_frag(std::unordered_multiset< _Key, _Hash, _Compare, _Alloc >), "header", fragment=SWIG_Traits_frag(_Key), - fragment="StdMultisetTraits") { + fragment="StdUnorderedMultisetTraits") { namespace swig { template <> struct traits > { typedef pointer_category category; From 37af90a50e93ac7f5fb50cac08326781ded6da14 Mon Sep 17 00:00:00 2001 From: Takashi Tamura Date: Sun, 29 Jan 2017 11:11:55 +0900 Subject: [PATCH 4/8] use equal_range instead of upper_bound. unordered containers do not have the upper_bound method. --- Lib/ruby/std_multimap.i | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/ruby/std_multimap.i b/Lib/ruby/std_multimap.i index 3e06ee12c..762a87653 100644 --- a/Lib/ruby/std_multimap.i +++ b/Lib/ruby/std_multimap.i @@ -90,12 +90,11 @@ %extend { VALUE __getitem__(const key_type& key) const { - MultiMap::const_iterator i = self->find(key); - if ( i != self->end() ) + std::pair r = $self->equal_range(key); + if ( r.first != r.second ) { - MultiMap::const_iterator e = $self->upper_bound(key); VALUE ary = rb_ary_new(); - for ( ; i != e; ++i ) + for (MultiMap::const_iterator i = r.first ; i != r.second; ++i ) { rb_ary_push( ary, swig::from( i->second ) ); } From d29a325b99cdeb5b845db0defbfffc7956be031a Mon Sep 17 00:00:00 2001 From: Takashi Tamura Date: Sun, 29 Jan 2017 11:17:18 +0900 Subject: [PATCH 5/8] [ruby] support for std unordered containers. --- Lib/ruby/std_unordered_map.i | 83 ++++++++++++++++++++++++ Lib/ruby/std_unordered_multimap.i | 102 ++++++++++++++++++++++++++++++ Lib/ruby/std_unordered_multiset.i | 50 +++++++++++++++ Lib/ruby/std_unordered_set.i | 54 ++++++++++++++++ 4 files changed, 289 insertions(+) create mode 100644 Lib/ruby/std_unordered_map.i create mode 100644 Lib/ruby/std_unordered_multimap.i create mode 100644 Lib/ruby/std_unordered_multiset.i create mode 100644 Lib/ruby/std_unordered_set.i diff --git a/Lib/ruby/std_unordered_map.i b/Lib/ruby/std_unordered_map.i new file mode 100644 index 000000000..618336e8c --- /dev/null +++ b/Lib/ruby/std_unordered_map.i @@ -0,0 +1,83 @@ +// +// Maps +// +%include + +%fragment("StdUnorderedMapTraits","header",fragment="StdMapCommonTraits") +{ + namespace swig { + template + inline void + assign(const RubySeq& rubyseq, std::unordered_map *map) { + typedef typename std::unordered_map::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + map->insert(value_type(it->first, it->second)); + } + } + + template + struct traits_asptr > { + typedef std::unordered_map map_type; + static int asptr(VALUE obj, map_type **val) { + int res = SWIG_ERROR; + if ( TYPE(obj) == T_HASH ) { + static ID id_to_a = rb_intern("to_a"); + VALUE items = rb_funcall(obj, id_to_a, 0); + res = traits_asptr_stdseq, std::pair >::asptr(items, val); + } else { + map_type *p; + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; + if (SWIG_IsOK(res) && val) *val = p; + } + return res; + } + }; + + template + struct traits_from > { + typedef std::unordered_map map_type; + typedef typename map_type::const_iterator const_iterator; + typedef typename map_type::size_type size_type; + + static VALUE from(const map_type& map) { + swig_type_info *desc = swig::type_info(); + if (desc && desc->clientdata) { + return SWIG_NewPointerObj(new map_type(map), desc, SWIG_POINTER_OWN); + } else { + size_type size = map.size(); + int rubysize = (size <= (size_type) INT_MAX) ? (int) size : -1; + if (rubysize < 0) { + SWIG_RUBY_THREAD_BEGIN_BLOCK; + rb_raise( rb_eRuntimeError, "map size not valid in Ruby"); + SWIG_RUBY_THREAD_END_BLOCK; + return Qnil; + } + VALUE obj = rb_hash_new(); + for (const_iterator i= map.begin(); i!= map.end(); ++i) { + VALUE key = swig::from(i->first); + VALUE val = swig::from(i->second); + rb_hash_aset(obj, key, val); + } + return obj; + } + } + }; + } +} + +#define %swig_unordered_map_common(Map...) %swig_map_common(Map) +#define %swig_unordered_map_methods(Map...) %swig_map_methods(Map) + +%rename("delete") std::unordered_map::__delete__; +%rename("reject!") std::unordered_map::reject_bang; +%rename("map!") std::unordered_map::map_bang; +%rename("empty?") std::unordered_map::empty; +%rename("include?") std::unordered_map::__contains__ const; +%rename("has_key?") std::unordered_map::has_key const; + +%mixin std::map "Enumerable"; +%alias std::unordered_map::push "<<"; + +%include diff --git a/Lib/ruby/std_unordered_multimap.i b/Lib/ruby/std_unordered_multimap.i new file mode 100644 index 000000000..2171c7e85 --- /dev/null +++ b/Lib/ruby/std_unordered_multimap.i @@ -0,0 +1,102 @@ +/* + Multimaps +*/ +%include + +%fragment("StdUnorderedMultimapTraits","header",fragment="StdMapCommonTraits") +{ + namespace swig { + template + inline void + assign(const RubySeq& rubyseq, std::unordered_multimap *multimap) { + typedef typename std::unordered_multimap::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + multimap->insert(value_type(it->first, it->second)); + } + } + + template + struct traits_asptr > { + typedef std::unordered_multimap multimap_type; + static int asptr(VALUE obj, std::unordered_multimap **val) { + int res = SWIG_ERROR; + if ( TYPE(obj) == T_HASH ) { + static ID id_to_a = rb_intern("to_a"); + VALUE items = rb_funcall(obj, id_to_a, 0); + return traits_asptr_stdseq, std::pair >::asptr(items, val); + } else { + multimap_type *p; + res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + if (SWIG_IsOK(res) && val) *val = p; + } + return res; + } + }; + + template + struct traits_from > { + typedef std::unordered_multimap multimap_type; + typedef typename multimap_type::const_iterator const_iterator; + typedef typename multimap_type::size_type size_type; + + static VALUE from(const multimap_type& multimap) { + swig_type_info *desc = swig::type_info(); + if (desc && desc->clientdata) { + return SWIG_NewPointerObj(new multimap_type(multimap), desc, SWIG_POINTER_OWN); + } else { + size_type size = multimap.size(); + int rubysize = (size <= (size_type) INT_MAX) ? (int) size : -1; + if (rubysize < 0) { + SWIG_RUBY_THREAD_BEGIN_BLOCK; + rb_raise(rb_eRuntimeError, + "multimap_ size not valid in Ruby"); + SWIG_RUBY_THREAD_END_BLOCK; + return Qnil; + } + VALUE obj = rb_hash_new(); + for (const_iterator i= multimap.begin(); i!= multimap.end(); ++i) { + VALUE key = swig::from(i->first); + VALUE val = swig::from(i->second); + + VALUE oldval = rb_hash_aref( obj, key ); + if ( oldval == Qnil ) + rb_hash_aset(obj, key, val); + else { + // Multiple values for this key, create array if needed + // and add a new element to it. + VALUE ary; + if ( TYPE(oldval) == T_ARRAY ) + ary = oldval; + else + { + ary = rb_ary_new2(2); + rb_ary_push( ary, oldval ); + rb_hash_aset( obj, key, ary ); + } + rb_ary_push( ary, val ); + } + + } + return obj; + } + } + }; + } +} + +#define %swig_unordered_multimap_methods(MultiMap...) %swig_multimap_methods(MultiMap) + +%mixin std::unordered_multimap "Enumerable"; + +%rename("delete") std::unordered_multimap::__delete__; +%rename("reject!") std::unordered_multimap::reject_bang; +%rename("map!") std::unordered_multimap::map_bang; +%rename("empty?") std::unordered_multimap::empty; +%rename("include?" ) std::unordered_multimap::__contains__ const; +%rename("has_key?" ) std::unordered_multimap::has_key const; + +%alias std::unordered_multimap::push "<<"; + +%include + diff --git a/Lib/ruby/std_unordered_multiset.i b/Lib/ruby/std_unordered_multiset.i new file mode 100644 index 000000000..5d51abf77 --- /dev/null +++ b/Lib/ruby/std_unordered_multiset.i @@ -0,0 +1,50 @@ +/* + Multisets +*/ + +%include + +%fragment("StdUnorderedMultisetTraits","header",fragment="StdSequenceTraits") +%{ + namespace swig { + template + inline void + assign(const RubySeq& rubyseq, std::unordered_multiset* seq) { + // seq->insert(rubyseq.begin(), rubyseq.end()); // not used as not always implemented + typedef typename RubySeq::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + seq->insert(seq->end(),(value_type)(*it)); + } + } + + template + struct traits_asptr > { + static int asptr(VALUE obj, std::unordered_multiset **m) { + return traits_asptr_stdseq >::asptr(obj, m); + } + }; + + template + struct traits_from > { + static VALUE from(const std::unordered_multiset& vec) { + return traits_from_stdseq >::from(vec); + } + }; + } +%} + +#define %swig_unordered_multiset_methods(Set...) %swig_unordered_set_methods(Set) + + + +%rename("delete") std::unordered_multiset::__delete__; +%rename("reject!") std::unordered_multiset::reject_bang; +%rename("map!") std::unordered_multiset::map_bang; +%rename("empty?") std::unordered_multiset::empty; +%rename("include?") std::unordered_multiset::__contains__ const; +%rename("has_key?") std::unordered_multiset::has_key const; + +%alias std::unordered_multiset::push "<<"; + +%include diff --git a/Lib/ruby/std_unordered_set.i b/Lib/ruby/std_unordered_set.i new file mode 100644 index 000000000..6794d5d78 --- /dev/null +++ b/Lib/ruby/std_unordered_set.i @@ -0,0 +1,54 @@ +/* + Sets +*/ + +%include + +%fragment("StdUnorderedSetTraits","header",fragment="",fragment="StdSequenceTraits") +%{ + namespace swig { + template + inline void + assign(const RubySeq& rubyseq, std::unordered_set* seq) { + // seq->insert(rubyseq.begin(), rubyseq.end()); // not used as not always implemented + typedef typename RubySeq::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + seq->insert(seq->end(),(value_type)(*it)); + } + } + + template + struct traits_asptr > { + static int asptr(VALUE obj, std::unordered_set **s) { + return traits_asptr_stdseq >::asptr(obj, s); + } + }; + + template + struct traits_from > { + static VALUE from(const std::unordered_set& vec) { + return traits_from_stdseq >::from(vec); + } + }; + } +%} + +#define %swig_unordered_set_methods(set...) %swig_set_methods(set) + +%mixin std::unordered_set "Enumerable"; + + + +%rename("delete") std::unordered_set::__delete__; +%rename("reject!") std::unordered_set::reject_bang; +%rename("map!") std::unordered_set::map_bang; +%rename("empty?") std::unordered_set::empty; +%rename("include?" ) std::unordered_set::__contains__ const; +%rename("has_key?" ) std::unordered_set::has_key const; + +%alias std::unordered_set::push "<<"; + + +%include + From ec9b380c0c46a4f13d12179619759a7f748e7e97 Mon Sep 17 00:00:00 2001 From: Takashi Tamura Date: Sun, 29 Jan 2017 11:18:53 +0900 Subject: [PATCH 6/8] [ruby] add tests for unordered containers. --- Examples/test-suite/common.mk | 2 +- Examples/test-suite/cpp11_hash_tables.i | 32 +++++++++----- .../ruby/cpp11_hash_tables_runme.rb | 44 +++++++++++++++++++ 3 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 Examples/test-suite/ruby/cpp11_hash_tables_runme.rb diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 8d97b4bf9..1d35e0fc2 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -545,6 +545,7 @@ CPP11_TEST_CASES = \ cpp11_explicit_conversion_operators \ cpp11_final_override \ cpp11_function_objects \ + cpp11_hash_tables \ cpp11_inheriting_constructors \ cpp11_initializer_list \ cpp11_initializer_list_extend \ @@ -572,7 +573,6 @@ CPP11_TEST_CASES = \ # Broken C++11 test cases. CPP11_TEST_BROKEN = \ -# cpp11_hash_tables \ # not fully implemented yet # cpp11_variadic_templates \ # Broken for some languages (such as Java) # cpp11_reference_wrapper \ # No typemaps diff --git a/Examples/test-suite/cpp11_hash_tables.i b/Examples/test-suite/cpp11_hash_tables.i index 4f68cbac5..0c671aa5d 100644 --- a/Examples/test-suite/cpp11_hash_tables.i +++ b/Examples/test-suite/cpp11_hash_tables.i @@ -4,19 +4,27 @@ %inline %{ #include -//#include +#include #include -//#include +#include %} %include "std_set.i" -//%include "std_map.i" +%include "std_multiset.i" +%include "std_map.i" +%include "std_multimap.i" %include "std_unordered_set.i" -//%include "std_unordered_map.i" +%include "std_unordered_multiset.i" +%include "std_unordered_map.i" +%include "std_unordered_multimap.i" %template (SetInt) std::set; -//%template (MapIntInt) std::map; +%template (MultiSetInt) std::multiset; +%template (MapIntInt) std::map; +%template (MultiMapIntInt) std::multimap; %template (UnorderedSetInt) std::unordered_set; -//%template (UnorderedMapIntInt) std::unordered_map; +%template (UnorderedMultiSetInt) std::unordered_multiset; +%template (UnorderedMapIntInt) std::unordered_map; +%template (UnorderedMultiMapIntInt) std::unordered_multimap; %inline %{ using namespace std; @@ -25,19 +33,19 @@ class MyClass { public: set getSet() { return _set; } void addSet(int elt) { _set.insert(_set.begin(), elt); } -// map getMap() { return _map; } -// void addMap(int elt1, int elt2) { _map.insert(make_pair(elt1, elt2)); } + map getMap() { return _map; } + void addMap(int elt1, int elt2) { _map.insert(make_pair(elt1, elt2)); } unordered_set getUnorderedSet() { return _unordered_set; } void addUnorderedSet(int elt) { _unordered_set.insert(_unordered_set.begin(), elt); } -// unordered_map getUnorderedMap() { return _unordered_map; } -// void addUnorderedMap(int elt1, int elt2) { _unordered_map.insert(make_pair(elt1, elt2)); } + unordered_map getUnorderedMap() { return _unordered_map; } + void addUnorderedMap(int elt1, int elt2) { _unordered_map.insert(make_pair(elt1, elt2)); } private: set _set; -// map _map; + map _map; unordered_set _unordered_set; -// unordered_map _unordered_map; + unordered_map _unordered_map; }; %} diff --git a/Examples/test-suite/ruby/cpp11_hash_tables_runme.rb b/Examples/test-suite/ruby/cpp11_hash_tables_runme.rb new file mode 100644 index 000000000..db910505e --- /dev/null +++ b/Examples/test-suite/ruby/cpp11_hash_tables_runme.rb @@ -0,0 +1,44 @@ +require 'swig_assert' +require 'cpp11_hash_tables' + +[Cpp11_hash_tables::MapIntInt.new({1=>7}), + Cpp11_hash_tables::MultiMapIntInt.new({1=>7}), + Cpp11_hash_tables::UnorderedMapIntInt.new({1=>7}), + Cpp11_hash_tables::UnorderedMultiMapIntInt.new({1=>7})].each{|x| + swig_assert_equal("x[1]", "7", binding) + swig_assert_equal("x[2]", "nil", binding) + x[2] = 9 + swig_assert_equal("x[2]", "9", binding) + x.delete(2) + swig_assert_equal("x[2]", "nil", binding) + swig_assert_equal("x.empty?", "false", binding) + x.delete(1) + swig_assert_equal("x.empty?", "true", binding) + swig_assert_equal("x.include?(1)", "false", binding) +} + +[Cpp11_hash_tables::MultiMapIntInt.new({1=>7}), + Cpp11_hash_tables::UnorderedMultiMapIntInt.new({1=>7})].each{|x| + x[1] = 9 + swig_assert_equal("x[1].sort", "[7,9]", binding) +} + +[Cpp11_hash_tables::SetInt.new([1]), + Cpp11_hash_tables::MultiSetInt.new([1]), + Cpp11_hash_tables::UnorderedSetInt.new([1]), + Cpp11_hash_tables::UnorderedMultiSetInt.new([1])].each{|x| + swig_assert_equal("x.include?(1)", "true", binding) + swig_assert_equal("x.include?(2)", "false", binding) + x << 2 + swig_assert_equal("x.include?(2)", "true", binding) + x.erase(2) + swig_assert_equal("x.empty?", "false", binding) + x.erase(1) + swig_assert_equal("x.empty?", "true", binding) +} + +[Cpp11_hash_tables::MultiSetInt.new([1]), + Cpp11_hash_tables::UnorderedMultiSetInt.new([1])].each{|x| + x << 1 + swig_assert_equal("x.count(1)", "2", binding) +} From 50f556de3956982dc076135904b83574e0e81896 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 10 Feb 2017 19:26:02 +0000 Subject: [PATCH 7/8] Cosmetic changes in C++11 std_unordered support files --- Lib/ruby/std_unordered_map.i | 4 ++-- Lib/ruby/std_unordered_multimap.i | 22 ++++++++++------------ Lib/ruby/std_unordered_multiset.i | 2 -- Lib/ruby/std_unordered_set.i | 4 ---- Lib/std/std_unordered_map.i | 3 --- Lib/std/std_unordered_multimap.i | 3 --- Lib/std/std_unordered_multiset.i | 3 --- Lib/std/std_unordered_set.i | 3 --- 8 files changed, 12 insertions(+), 32 deletions(-) diff --git a/Lib/ruby/std_unordered_map.i b/Lib/ruby/std_unordered_map.i index 618336e8c..b2cef6520 100644 --- a/Lib/ruby/std_unordered_map.i +++ b/Lib/ruby/std_unordered_map.i @@ -21,7 +21,7 @@ typedef std::unordered_map map_type; static int asptr(VALUE obj, map_type **val) { int res = SWIG_ERROR; - if ( TYPE(obj) == T_HASH ) { + if (TYPE(obj) == T_HASH) { static ID id_to_a = rb_intern("to_a"); VALUE items = rb_funcall(obj, id_to_a, 0); res = traits_asptr_stdseq, std::pair >::asptr(items, val); @@ -50,7 +50,7 @@ int rubysize = (size <= (size_type) INT_MAX) ? (int) size : -1; if (rubysize < 0) { SWIG_RUBY_THREAD_BEGIN_BLOCK; - rb_raise( rb_eRuntimeError, "map size not valid in Ruby"); + rb_raise(rb_eRuntimeError, "map size not valid in Ruby"); SWIG_RUBY_THREAD_END_BLOCK; return Qnil; } diff --git a/Lib/ruby/std_unordered_multimap.i b/Lib/ruby/std_unordered_multimap.i index 2171c7e85..b663c1298 100644 --- a/Lib/ruby/std_unordered_multimap.i +++ b/Lib/ruby/std_unordered_multimap.i @@ -59,24 +59,22 @@ VALUE key = swig::from(i->first); VALUE val = swig::from(i->second); - VALUE oldval = rb_hash_aref( obj, key ); - if ( oldval == Qnil ) + VALUE oldval = rb_hash_aref(obj, key); + if (oldval == Qnil) { rb_hash_aset(obj, key, val); - else { + } else { // Multiple values for this key, create array if needed // and add a new element to it. VALUE ary; - if ( TYPE(oldval) == T_ARRAY ) + if (TYPE(oldval) == T_ARRAY) { ary = oldval; - else - { - ary = rb_ary_new2(2); - rb_ary_push( ary, oldval ); - rb_hash_aset( obj, key, ary ); - } - rb_ary_push( ary, val ); + } else { + ary = rb_ary_new2(2); + rb_ary_push(ary, oldval); + rb_hash_aset(obj, key, ary); + } + rb_ary_push(ary, val); } - } return obj; } diff --git a/Lib/ruby/std_unordered_multiset.i b/Lib/ruby/std_unordered_multiset.i index 5d51abf77..8e0a62b30 100644 --- a/Lib/ruby/std_unordered_multiset.i +++ b/Lib/ruby/std_unordered_multiset.i @@ -36,8 +36,6 @@ #define %swig_unordered_multiset_methods(Set...) %swig_unordered_set_methods(Set) - - %rename("delete") std::unordered_multiset::__delete__; %rename("reject!") std::unordered_multiset::reject_bang; %rename("map!") std::unordered_multiset::map_bang; diff --git a/Lib/ruby/std_unordered_set.i b/Lib/ruby/std_unordered_set.i index 6794d5d78..5279bbed5 100644 --- a/Lib/ruby/std_unordered_set.i +++ b/Lib/ruby/std_unordered_set.i @@ -38,8 +38,6 @@ %mixin std::unordered_set "Enumerable"; - - %rename("delete") std::unordered_set::__delete__; %rename("reject!") std::unordered_set::reject_bang; %rename("map!") std::unordered_set::map_bang; @@ -49,6 +47,4 @@ %alias std::unordered_set::push "<<"; - %include - diff --git a/Lib/std/std_unordered_map.i b/Lib/std/std_unordered_map.i index 9212eab46..0d6986497 100644 --- a/Lib/std/std_unordered_map.i +++ b/Lib/std/std_unordered_map.i @@ -1,8 +1,5 @@ // // std::unordered_map -// Work in progress - the code is not compilable yet: -// operator--() and constructor(compare function) not available for unordered_ -// types // %include %include diff --git a/Lib/std/std_unordered_multimap.i b/Lib/std/std_unordered_multimap.i index 41520d42d..6f1be9cfa 100644 --- a/Lib/std/std_unordered_multimap.i +++ b/Lib/std/std_unordered_multimap.i @@ -1,8 +1,5 @@ // // std::unordered_multimap -// Work in progress - the code is not compilable yet: -// operator--() and constructor(compare function) not available for unordered_ -// types // %include diff --git a/Lib/std/std_unordered_multiset.i b/Lib/std/std_unordered_multiset.i index 50acb9dd7..1817fc24a 100644 --- a/Lib/std/std_unordered_multiset.i +++ b/Lib/std/std_unordered_multiset.i @@ -1,8 +1,5 @@ // // std::unordered_multiset -// Work in progress - the code is not compilable yet: -// operator--() and constructor(compare function) not available for unordered_ -// types // %include diff --git a/Lib/std/std_unordered_set.i b/Lib/std/std_unordered_set.i index fb4415e1a..75e955c4b 100644 --- a/Lib/std/std_unordered_set.i +++ b/Lib/std/std_unordered_set.i @@ -1,8 +1,5 @@ // // std::unordered_set -// Work in progress - the code is not compilable yet: -// operator--() and constructor(compare function) not available for unordered_ -// types // %include From 16b583ec25ff34b152d919f41697229be7df9ece Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 10 Feb 2017 19:27:57 +0000 Subject: [PATCH 8/8] Move cpp11_hash_tables test to Ruby makefile until other languages work --- Examples/test-suite/common.mk | 3 +-- Examples/test-suite/ruby/Makefile.in | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 1d35e0fc2..39d4f1fa6 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -534,7 +534,7 @@ CPP_TEST_CASES += \ wrapmacro # C++11 test cases. -CPP11_TEST_CASES = \ +CPP11_TEST_CASES += \ cpp11_alignment \ cpp11_alternate_function_syntax \ cpp11_constexpr \ @@ -545,7 +545,6 @@ CPP11_TEST_CASES = \ cpp11_explicit_conversion_operators \ cpp11_final_override \ cpp11_function_objects \ - cpp11_hash_tables \ cpp11_inheriting_constructors \ cpp11_initializer_list \ cpp11_initializer_list_extend \ diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in index d94ac7061..a127860b0 100644 --- a/Examples/test-suite/ruby/Makefile.in +++ b/Examples/test-suite/ruby/Makefile.in @@ -29,6 +29,9 @@ CPP_TEST_CASES = \ # ruby_li_std_speed # stl_new +CPP11_TEST_CASES = \ + cpp11_hash_tables \ + C_TEST_CASES += \ li_cstring \ ruby_manual_proxy \