Skip to content

Commit 3a6d9f6

Browse files
committed
Support Buffer of const elements.
1 parent b7693d6 commit 3a6d9f6

File tree

3 files changed

+58
-7
lines changed

3 files changed

+58
-7
lines changed

rice/Buffer.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ namespace Rice
5050

5151
bool m_owner = false;
5252
size_t m_size = 0;
53-
// std::unique_ptr would be greate but std::unique_ptr<void> isn't allowed
54-
T* m_buffer = nullptr;
53+
// std::unique_ptr would be great but std::unique_ptr<void> isn't allowed. Mutable is needed to
54+
// support const T* buffers
55+
mutable T* m_buffer = nullptr;
5556
};
5657

5758
template<typename T>

rice/Buffer.ipp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ namespace Rice
5252
this->m_buffer = new T[this->m_size]();
5353

5454
String packed = array.pack<Intrinsic_T>();
55-
memcpy(this->m_buffer, RSTRING_PTR(packed.value()), RSTRING_LEN(packed.value()));
55+
memcpy((void*)this->m_buffer, RSTRING_PTR(packed.value()), RSTRING_LEN(packed.value()));
5656

5757
this->m_owner = true;
5858
break;
@@ -69,18 +69,18 @@ namespace Rice
6969
{
7070
this->m_buffer = new T[this->m_size]();
7171
}
72-
memcpy(this->m_buffer, RSTRING_PTR(value), this->m_size);
72+
memcpy((void*)this->m_buffer, RSTRING_PTR(value), this->m_size);
7373

7474
this->m_owner = true;
7575
break;
7676
}
7777
case RUBY_T_DATA:
7878
{
79-
if (Data_Type<T>::is_descendant(value))
79+
if (Data_Type<std::remove_cv_t<T>>::is_descendant(value))
8080
{
8181
this->m_size = 1;
8282
this->m_buffer = new T[this->m_size]();
83-
this->m_buffer[0] = *detail::unwrap<T>(value, Data_Type<T>::ruby_data_type(), false);
83+
(std::remove_cv_t<T>)this->m_buffer[0] = *detail::unwrap<T>(value, Data_Type<std::remove_cv_t<T>>::ruby_data_type(), false);
8484
this->m_owner = false;
8585
break;
8686
}
@@ -94,7 +94,7 @@ namespace Rice
9494
T data = detail::protect(RubyType_T::fromRuby, value);
9595
this->m_size = 1;
9696
this->m_buffer = new T[this->m_size]();
97-
memcpy(this->m_buffer, &data, sizeof(T));
97+
memcpy((void*)this->m_buffer, &data, sizeof(T));
9898
this->m_owner = true;
9999
break;
100100
}

test/test_Buffer.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,31 @@ TESTCASE(CharArray)
6464
ASSERT_EQUAL(data[7], 1);
6565
}
6666

67+
TESTCASE(ConstChar)
68+
{
69+
define_buffer<const char>();
70+
71+
Module m = define_module("BufferTesting");
72+
73+
std::string code = R"(Rice::Buffer≺char const≻.new("my string"))";
74+
Object object = m.instance_eval(code);
75+
ASSERT_EQUAL("Rice::Buffer≺char const≻", object.class_name().c_str());
76+
77+
String bytes = object.call("bytes");
78+
ASSERT_EQUAL(std::string("my string"), bytes.str());
79+
80+
Array array = object.call("to_ary");
81+
ASSERT_EQUAL("109, 121, 32, 115, 116, 114, 105, 110, 103", array.join(", ").c_str());
82+
83+
Object size = object.call("size");
84+
ASSERT_EQUAL(9, detail::From_Ruby<int>().convert(size));
85+
86+
Data_Object<Buffer<const char>> dataObject(object);
87+
Buffer<const char> buffer = std::move(*dataObject);
88+
ASSERT_EQUAL(std::string("my string"), std::string(buffer.ptr(), buffer.size()));
89+
ASSERT_EQUAL(9, (int)buffer.size());
90+
}
91+
6792
TESTCASE(signed_char_pointer)
6893
{
6994
define_buffer<signed char>();
@@ -330,6 +355,31 @@ TESTCASE(array_of_objects)
330355
Object result = m.module_eval(code);
331356
ASSERT_EQUAL(1, detail::From_Ruby<int>().convert(result));
332357

358+
code = R"(array = [MyClass.new(0), MyClass.new(1)]
359+
buffer = Rice::Buffer≺AnonymousNamespace꞉꞉MyClass∗≻.new(array)
360+
buffer[1] = MyClass.new(2)
361+
buffer[1].id)";
362+
363+
result = m.module_eval(code);
364+
ASSERT_EQUAL(2, detail::From_Ruby<int>().convert(result));
365+
}
366+
367+
TESTCASE(array_of_const_objects)
368+
{
369+
define_buffer<const MyClass*>();
370+
371+
define_class<MyClass>("MyClass").
372+
define_constructor(Constructor<MyClass, int>()).
373+
define_attr("id", &MyClass::id);
374+
375+
std::string code = R"(array = [MyClass.new(0), MyClass.new(1)]
376+
buffer = Rice::Buffer≺AnonymousNamespace꞉꞉MyClass∗≻.new(array)
377+
buffer[1].id)";
378+
379+
Module m = define_module("Testing");
380+
Object result = m.module_eval(code);
381+
ASSERT_EQUAL(1, detail::From_Ruby<int>().convert(result));
382+
333383
code = R"(array = [MyClass.new(0), MyClass.new(1)]
334384
buffer = Rice::Buffer≺AnonymousNamespace꞉꞉MyClass∗≻.new(array)
335385
buffer[1] = MyClass.new(2)

0 commit comments

Comments
 (0)