Ruby STL container setting slices fixes
Setting an STL container wrapper slice better matches the way Ruby arrays work. The behaviour is now the same as Ruby arrays. The only exception is the default value used when expanding a container cannot be nil as this is not a valid type/value for C++ container elements.
This commit is contained in:
parent
cd33aba427
commit
bb2523a003
4 changed files with 68 additions and 22 deletions
|
|
@ -72,13 +72,12 @@ ai = ArrayInt6.new()
|
|||
compare_containers([0, 0, 0, 0, 0, 0], ai)
|
||||
|
||||
# Set slice
|
||||
#newvals = [10, 20, 30, 40, 50, 60]
|
||||
#ai[0..5] = newvals
|
||||
#compare_containers(ai, newvals)
|
||||
newvals = [10, 20, 30, 40, 50, 60]
|
||||
ai[0, 6] = newvals
|
||||
compare_containers(ai, newvals)
|
||||
|
||||
#newvals = [10000, 20000, 30000, 40000, 50000, 60000]
|
||||
#ai[0..100] = newvals
|
||||
#compare_containers(ai, newvals[0..100])
|
||||
ai[-6, 6] = newvals
|
||||
compare_containers(ai, newvals)
|
||||
|
||||
setslice_exception(ai, [1, 2, 3, 4, 5, 6, 7])
|
||||
setslice_exception(ai, [1, 2, 3, 4, 5])
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ end
|
|||
def compare_sequences(a, b)
|
||||
if a != nil && b != nil
|
||||
if a.size != b.size
|
||||
failed(a, b, "different sizes")
|
||||
failed(a, b, "different sizes")
|
||||
end
|
||||
for i in 0..a.size-1
|
||||
failed(a, b, "elements are different") if a[i] != b[i]
|
||||
|
|
@ -121,9 +121,26 @@ def compare_sequences(a, b)
|
|||
end
|
||||
end
|
||||
|
||||
def compare_expanded_sequences(a, b)
|
||||
# a can contain nil elements which indicate additional elements
|
||||
# b won't contain nil for additional elements
|
||||
if a != nil && b != nil
|
||||
if a.size != b.size
|
||||
failed(a, b, "different sizes")
|
||||
end
|
||||
for i in 0..a.size-1
|
||||
failed(a, b, "elements are different") if a[i] != b[i] && a[i] != nil
|
||||
end
|
||||
else
|
||||
unless a == nil && b == nil
|
||||
failed(a, b, "only one of the sequences is nil")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def check_slice(i, length)
|
||||
aa = [0,1,2,3]
|
||||
iv = IntVector.new([0,1,2,3])
|
||||
aa = [1,2,3,4]
|
||||
iv = IntVector.new(aa)
|
||||
|
||||
aa_slice = aa[i, length]
|
||||
iv_slice = iv[i, length]
|
||||
|
|
@ -135,8 +152,8 @@ def check_slice(i, length)
|
|||
end
|
||||
|
||||
def check_range(i, j)
|
||||
aa = [0,1,2,3]
|
||||
iv = IntVector.new([0,1,2,3])
|
||||
aa = [1,2,3,4]
|
||||
iv = IntVector.new(aa)
|
||||
|
||||
aa_range = aa[i..j]
|
||||
iv_range = iv[i..j]
|
||||
|
|
@ -147,6 +164,21 @@ def check_range(i, j)
|
|||
compare_sequences(aa_range, iv_range)
|
||||
end
|
||||
|
||||
def set_slice(i, length, expect_nil_expanded_elements)
|
||||
aa = [1,2,3,4]
|
||||
iv = IntVector.new(aa)
|
||||
aa_new = [8, 9]
|
||||
iv_new = IntVector.new(aa_new)
|
||||
|
||||
aa[i, length] = aa_new
|
||||
iv[i, length] = iv_new
|
||||
if expect_nil_expanded_elements
|
||||
compare_expanded_sequences(aa, iv)
|
||||
else
|
||||
compare_sequences(aa, iv)
|
||||
end
|
||||
end
|
||||
|
||||
for i in -5..5
|
||||
for length in -5..5
|
||||
check_slice(i, length)
|
||||
|
|
@ -159,6 +191,18 @@ for i in -5..5
|
|||
end
|
||||
end
|
||||
|
||||
for i in -4..4
|
||||
for length in 0..4
|
||||
set_slice(i, length, false)
|
||||
end
|
||||
end
|
||||
|
||||
for i in [5, 6]
|
||||
for length in 0..5
|
||||
set_slice(i, length, true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
dv = DoubleVector.new(10)
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ namespace swig {
|
|||
inline Sequence*
|
||||
getslice(const Sequence* self, Difference i, Difference j) {
|
||||
typename Sequence::size_type size = self->size();
|
||||
typename Sequence::size_type ii = (i == size && j == size) ? i : swig::check_index(i, size);
|
||||
typename Sequence::size_type ii = swig::check_index(i, size, (i == size && j == size));
|
||||
typename Sequence::size_type jj = swig::slice_index(j, size);
|
||||
|
||||
if (jj > ii) {
|
||||
|
|
@ -847,16 +847,20 @@ namespace swig
|
|||
return swig::from< Sequence::value_type >( x );
|
||||
}
|
||||
|
||||
VALUE __setitem__(difference_type i, difference_type j, const Sequence& v) throw (std::invalid_argument)
|
||||
{
|
||||
VALUE __setitem__(difference_type i, difference_type length, const Sequence& v) throw (std::invalid_argument) {
|
||||
|
||||
if ( j <= 0 ) return Qnil;
|
||||
if ( length < 0 )
|
||||
return Qnil;
|
||||
std::size_t len = $self->size();
|
||||
if ( i < 0 ) i = len - i;
|
||||
j += i;
|
||||
if ( static_cast<std::size_t>(j) >= len ) {
|
||||
swig::resize( $self, j+1, *(v.begin()) );
|
||||
j = len-1;
|
||||
if ( i < 0 ) {
|
||||
if ( i + static_cast<Sequence::difference_type>(len) < 0 )
|
||||
return Qnil;
|
||||
else
|
||||
i = len + i;
|
||||
}
|
||||
Sequence::difference_type j = length + i;
|
||||
if ( j > static_cast<Sequence::difference_type>(len) ) {
|
||||
swig::resize( $self, j, *(v.begin()) );
|
||||
}
|
||||
|
||||
VALUE r = Qnil;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
getslice(const std::array<T, N>* self, Difference i, Difference j) {
|
||||
using Sequence = std::array<T, N>;
|
||||
typename Sequence::size_type size = self->size();
|
||||
typename Sequence::size_type ii = (i == size && j == size) ? i : swig::check_index(i, size);
|
||||
typename Sequence::size_type ii = swig::check_index(i, size, (i == size && j == size));
|
||||
typename Sequence::size_type jj = swig::slice_index(j, size);
|
||||
|
||||
if (ii == 0 && jj == size) {
|
||||
|
|
@ -61,7 +61,6 @@
|
|||
typename Sequence::size_type ii = swig::check_index(i, size, true);
|
||||
typename Sequence::size_type jj = swig::slice_index(j, size);
|
||||
|
||||
std::cout << "setslice " << v[0] << " " << v[1] << std::endl;
|
||||
if (ii == 0 && jj == size) {
|
||||
std::copy(v.begin(), v.end(), self->begin());
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue