Skip to content
Snippets Groups Projects
Commit cfbbf789 authored by Jan Trávníček's avatar Jan Trávníček
Browse files

implementation and use of callback output iterator

parent 5481b2c8
No related branches found
No related tags found
No related merge requests found
...@@ -149,14 +149,8 @@ public: ...@@ -149,14 +149,8 @@ public:
* CommonException if one of the added elements is not available in context of datatype where the set is used * CommonException if one of the added elements is not available in context of datatype where the set is used
*/ */
void set ( SetComponentType data ) { void set ( SetComponentType data ) {
SetComponentType removed; std::set_difference ( m_data.begin ( ), m_data.end ( ), data.begin ( ), data.end ( ), ext::make_callback_iterator < const ComponentType & > ( std::bind ( & SetComponent::checkRemove, this, std::placeholders::_1 ) ) );
std::set_difference ( m_data.begin ( ), m_data.end ( ), data.begin ( ), data.end ( ), std::inserter ( removed, removed.end ( ) ) ); std::set_difference ( data.begin ( ), data.end ( ), m_data.begin ( ), m_data.end ( ), ext::make_callback_iterator < const ComponentType & > ( std::bind ( & SetComponent::checkAdd, this, std::placeholders::_1 ) ) );
for ( const ComponentType & element : removed )
checkRemove ( element );
for ( const ComponentType & element : data )
checkAdd ( element );
   
m_data = std::move ( data ); m_data = std::move ( data );
} }
......
...@@ -130,6 +130,17 @@ void ComponentsTest::testRemove ( ) { ...@@ -130,6 +130,17 @@ void ComponentsTest::testRemove ( ) {
tmp.accessComponent < GeneralAlphabet > ( ).add ( "1" ); tmp.accessComponent < GeneralAlphabet > ( ).add ( "1" );
tmp.accessComponent < NonlinearAlphabet > ( ).add ( "1" ); tmp.accessComponent < NonlinearAlphabet > ( ).add ( "1" );
CPPUNIT_ASSERT_THROW ( tmp.accessComponent < GeneralAlphabet > ( ).remove ( "1" ), exception::CommonException ); CPPUNIT_ASSERT_THROW ( tmp.accessComponent < GeneralAlphabet > ( ).remove ( "1" ), exception::CommonException );
CPPUNIT_ASSERT_THROW ( tmp.accessComponent < GeneralAlphabet > ( ).remove ( ext::linear_set < std::string > { "1" } ), exception::CommonException );
CPPUNIT_ASSERT_NO_THROW ( tmp.accessComponent < GeneralAlphabet > ( ).set ( ext::linear_set < std::string > { "1", "2", "aaa", "3" } ) );
CPPUNIT_ASSERT_THROW ( tmp.accessComponent < GeneralAlphabet > ( ).set ( ext::linear_set < std::string > { } ), exception::CommonException );
CPPUNIT_ASSERT ( tmp.accessComponent < GeneralAlphabet > ( ).get ( ).size ( ) == 4 );
CPPUNIT_ASSERT_NO_THROW ( tmp.accessComponent < NonlinearAlphabet > ( ).set ( ext::linear_set < std::string > { "1", "3" } ) );
CPPUNIT_ASSERT_THROW ( tmp.accessComponent < NonlinearAlphabet > ( ).set ( ext::linear_set < std::string > { "1", "4" } ), exception::CommonException );
tmp.accessComponent < NonlinearAlphabet > ( ).remove ( "1" ); tmp.accessComponent < NonlinearAlphabet > ( ).remove ( "1" );
tmp.accessComponent < GeneralAlphabet > ( ).remove ( "1" ); tmp.accessComponent < GeneralAlphabet > ( ).remove ( "1" );
} }
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define __ITERATOR_HPP_ #define __ITERATOR_HPP_
   
#include <iterator> #include <iterator>
#include <functional>
   
namespace ext { namespace ext {
   
...@@ -1025,6 +1026,80 @@ constexpr T * end ( T ( & arr ) [ N ] ) noexcept { ...@@ -1025,6 +1026,80 @@ constexpr T * end ( T ( & arr ) [ N ] ) noexcept {
return arr + N; return arr + N;
} }
   
/**
* \brief
* Output iterator calling a callback function on assignment
*
* \tparam the type of value accepted by the callback. The type must include the reference and cv-qualification if needed.
*/
template < class T >
class callback_iterator : public std::iterator < std::output_iterator_tag, void, void, void, void > {
/**
* The callback.
*/
std::function < void ( T ) > m_callback;
public:
/**
* Constructor of the callback iterator based on callback
*
* \param callback the function to call on asignment
*/
explicit callback_iterator ( std::function < void ( T ) > callback ) : m_callback ( callback ) {
}
/**
* Asignment operator calling the calback with the accepted parameter.
*
* \param value the value to pass to the callback
*
* \return reference to this iterator
*/
callback_iterator & operator = ( T value ) {
m_callback ( std::forward < T > ( value ) );
return * this;
}
/**
* Typical implementation of output iterator dereference operator producing itself.
*
* \return reference to this output iterator
*/
callback_iterator &operator * ( ) {
return * this;
}
/**
* Increment operator implementation as no operation.
*
* \return reference to this output iterator
*/
callback_iterator &operator ++ ( ) {
return * this;
}
/**
* Increment operator implementation as no operation.
*
* \return reference to this output iterator
*/
callback_iterator operator ++ ( int ) {
return * this;
}
};
/**
* Function to create callback iterator from the callback.
*
* \param T the type of value accepted by the callback.
*
* \return the callback iterator
*/
template < class T >
callback_iterator < T > make_callback_iterator ( const std::function < void ( T ) > & callback ) {
return callback_iterator < T > ( callback );
}
} /* namespace ext */ } /* namespace ext */
   
#endif /* __ITERATOR_HPP_ */ #endif /* __ITERATOR_HPP_ */
...@@ -69,3 +69,11 @@ void IteratorTest::testReverser() { ...@@ -69,3 +69,11 @@ void IteratorTest::testReverser() {
   
CPPUNIT_ASSERT ( data2 == trans ); CPPUNIT_ASSERT ( data2 == trans );
} }
void IteratorTest::testCallbackIterator ( ) {
int expected;
ext::callback_iterator < int > out = ext::make_callback_iterator < int > ( [ & ] ( int value ) -> void { CPPUNIT_ASSERT ( value == expected ); } );
expected = 10;
* out = 10;
}
...@@ -8,6 +8,7 @@ class IteratorTest : public CppUnit::TestFixture ...@@ -8,6 +8,7 @@ class IteratorTest : public CppUnit::TestFixture
CPPUNIT_TEST_SUITE( IteratorTest ); CPPUNIT_TEST_SUITE( IteratorTest );
CPPUNIT_TEST( testIterator ); CPPUNIT_TEST( testIterator );
CPPUNIT_TEST( testReverser ); CPPUNIT_TEST( testReverser );
CPPUNIT_TEST( testCallbackIterator );
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
   
public: public:
...@@ -16,6 +17,7 @@ public: ...@@ -16,6 +17,7 @@ public:
   
void testIterator(); void testIterator();
void testReverser(); void testReverser();
void testCallbackIterator();
}; };
   
#endif // ITERATOR_TEST_H_ #endif // ITERATOR_TEST_H_
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment