Skip to content

Commit

Permalink
Move semantics is implemented for initial value of behavior and behav…
Browse files Browse the repository at this point in the history
…ior_sink and for sending new values to behavior_sink and event_sink
  • Loading branch information
Alexander Mopleen committed Jan 10, 2015
1 parent d7e0c81 commit e471f09
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
5 changes: 5 additions & 0 deletions c++/sodium/light_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#ifndef _SODIUM_LIGHTPTR_H_
#define _SODIUM_LIGHTPTR_H_

#include <utility>

namespace sodium {
template <class A>
void deleter(void* a0)
Expand Down Expand Up @@ -38,6 +40,9 @@ namespace sodium {
template <class A> static inline name create(const A& a) { \
return name(new A(a), deleter<A>); \
} \
template <class A> static inline name create(A&& a) { \
return name(new A(std::move(a)), deleter<A>); \
} \
name(void* value, impl::deleter del); \
~name(); \
name& operator = (const name& other); \
Expand Down
21 changes: 21 additions & 0 deletions c++/sodium/sodium.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,11 @@ namespace sodium {
{
}

behavior(A&& a)
: impl::behavior_(light_ptr::create<A>(std::move(a)))
{
}

/*!
* Sample the value of this behavior.
*/
Expand Down Expand Up @@ -1190,6 +1195,11 @@ namespace sodium {
transaction<P> trans;
impl.send(trans.impl(), light_ptr::create<A>(a));
}

void send(A&& a) const {
transaction<P> trans;
impl.send(trans.impl(), light_ptr::create<A>(std::move(a)));
}
};

#if defined(SODIUM_NO_CXX11)
Expand Down Expand Up @@ -1298,10 +1308,21 @@ namespace sodium {
this->impl = SODIUM_SHARED_PTR<impl::behavior_impl>(hold(trans.impl(), light_ptr::create<A>(initA), e));
}

behavior_sink(A&& initA)
{
transaction<P> trans;
this->impl = SODIUM_SHARED_PTR<impl::behavior_impl>(hold(trans.impl(), light_ptr::create<A>(std::move(initA)), e));
}

void send(const A& a) const
{
e.send(a);
}

void send(A&& a) const
{
e.send(std::move(a));
}
};

namespace impl {
Expand Down
25 changes: 24 additions & 1 deletion c++/tests/test_sodium.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,7 @@ void test_sodium::detach_sink()
// Check that holding the sink doesn't prevent a cleanup added to an event
// from working.
event_sink<int>* esnk = new event_sink<int>;
shared_ptr<bool> cleanedUp(new bool(false));
SODIUM_SHARED_PTR<bool> cleanedUp(new bool(false));
event<int>* e(new event<int>(esnk->add_cleanup([cleanedUp] () {
*cleanedUp = true;
})));
Expand All @@ -1135,6 +1135,29 @@ void test_sodium::detach_sink()
delete esnk;
}

void test_sodium::move_semantics()
{
behavior<unique_ptr<int>> pointer(unique_ptr<int>(new int(625)));
int v = 0;
auto value = pointer.map<int>([&](const unique_ptr<int>& pInt) {
return pInt ? *pInt : 0;
});
CPPUNIT_ASSERT(value.sample() == 625);
}

void test_sodium::move_semantics_sink()
{
behavior_sink<unique_ptr<int>> bs(unique_ptr<int>(new int(1)));

int newValue = 0;
bs.updates().listen([&](const unique_ptr<int>& pInt) {
newValue = pInt ? *pInt : 0;
});

bs.send(unique_ptr<int>(new int(2)));
CPPUNIT_ASSERT(newValue == 2);
}

#endif

int main(int argc, char* argv[])
Expand Down
4 changes: 4 additions & 0 deletions c++/tests/test_sodium.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class test_sodium : public CppUnit::TestFixture {
CPPUNIT_TEST(lift_loop);
CPPUNIT_TEST(loop_switch_e);
CPPUNIT_TEST(detach_sink);
CPPUNIT_TEST(move_semantics);
CPPUNIT_TEST(move_semantics_sink);
#endif
CPPUNIT_TEST_SUITE_END();

Expand Down Expand Up @@ -140,6 +142,8 @@ class test_sodium : public CppUnit::TestFixture {
void lift_loop();
void loop_switch_e();
void detach_sink();
void move_semantics();
void move_semantics_sink();
#endif
};

Expand Down

0 comments on commit e471f09

Please sign in to comment.