From a0781f7190cdbfd3e53b76f29d9259a1e7f1c002 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Mon, 10 Sep 2018 22:44:53 +0200 Subject: [PATCH] allow comparison of variant with its content types --- alib2std/src/extensions/container/variant.hpp | 100 +++++++++++++++++- .../extensions/container/VariantTest.cpp | 2 + 2 files changed, 98 insertions(+), 4 deletions(-) diff --git a/alib2std/src/extensions/container/variant.hpp b/alib2std/src/extensions/container/variant.hpp index 970cec350a..197a400504 100644 --- a/alib2std/src/extensions/container/variant.hpp +++ b/alib2std/src/extensions/container/variant.hpp @@ -635,7 +635,7 @@ public: * \brief * Implementation of the three way comparison for varant. * - * \param other the value compared to compared this + * \param other the value compared to this * * \return negative value if this is smaller than the other instance, positive if this is greater than the other instance, zero othervise */ @@ -646,6 +646,25 @@ public: return helper_t::compareHelper(this->type_id, &this->data, other.type_id, &other.data); } + /** + * \brief + * Implementation of the three way comparison for varant. + * + * \tparam T the type of the other compared value + * + * \param other the value compared to this + * + * \return negative value if this is smaller than the other instance, positive if this is greater than the other instance, zero othervise + */ + template < typename T, typename std::enable_if < ext::is_in < T, Ts ... >::value >::type * = nullptr > + int compare ( const T & other ) const { + if ( this->type_id < ext::type_index ( typeid ( T ) ) ) return -1; + if ( this->type_id > ext::type_index ( typeid ( T ) ) ) return 1; + + static ext::compare < typename std::decay < T >::type > comp; + return comp ( this->template get < T > ( ), other ); + } + /** * \brief * Function to test whether the variant currently contains type T. @@ -932,7 +951,7 @@ public: * \brief * Implementation of the three way comparison for varant. * - * \param other the value compared to compared this + * \param other the value compared to this * * \return negative value if this is smaller than the other instance, positive if this is greater than the other instance, zero othervise */ @@ -941,6 +960,19 @@ public: return comp ( m_value, other.m_value ); } + /** + * \brief + * Implementation of the three way comparison for varant. + * + * \param other the value compared to this + * + * \return negative value if this is smaller than the other instance, positive if this is greater than the other instance, zero othervise + */ + int compare ( const T & other ) const { + static ext::compare < typename std::decay < T >::type > comp; + return comp ( m_value, other ); + } + /** * \brief * Function to test whether the variant currently contains type T. @@ -1174,7 +1206,7 @@ public: * \return negative value if this is smaller than the other instance, positive if this is greater than the other instance, zero othervise */ int compare ( const variant < void > & ) const { - return true; + return 0; } /** @@ -1284,11 +1316,71 @@ struct compare < ext::variant < Ts ... > > { * * \return string representation */ -template < class ... Ts > +template < class ... Ts > std::string to_string ( const ext::variant < Ts ... > & value ) { return ( std::string ) value; } +template < class ... Ts, class T > +bool operator < ( const ext::variant < Ts ... > & first, const T & second ) { + return first.compare ( second ) < 0; +} + +template < class ... Ts, class T > +bool operator > ( const ext::variant < Ts ... > & first, const T & second ) { + return first.compare ( second ) > 0; +} + +template < class ... Ts, class T > +bool operator <= ( const ext::variant < Ts ... > & first, const T & second ) { + return first.compare ( second ) <= 0; +} + +template < class ... Ts, class T > +bool operator >= ( const ext::variant < Ts ... > & first, const T & second ) { + return first.compare ( second ) >= 0; +} + +template < class ... Ts, class T > +bool operator == ( const ext::variant < Ts ... > & first, const T & second ) { + return first.compare ( second ) == 0; +} + +template < class ... Ts, class T > +bool operator != ( const ext::variant < Ts ... > & first, const T & second ) { + return first.compare ( second ) != 0; +} + +template < class ... Ts, class T > +bool operator < ( const T & first, const ext::variant < Ts ... > & second ) { + return second > first; +} + +template < class ... Ts, class T > +bool operator > ( const T & first, const ext::variant < Ts ... > & second ) { + return second < first; +} + +template < class ... Ts, class T > +bool operator <= ( const T & first, const ext::variant < Ts ... > & second ) { + return second >= first; +} + +template < class ... Ts, class T > +bool operator >= ( const T & first, const ext::variant < Ts ... > & second ) { + return second <= first; +} + +template < class ... Ts, class T > +bool operator == ( const T & first, const ext::variant < Ts ... > & second ) { + return second == first; +} + +template < class ... Ts, class T > +bool operator != ( const T & first, const ext::variant < Ts ... > & second ) { + return second != first; +} + /** * \brief * Class to help building of the variant type or, in case variant is requested to be constructed from single type or more types but all the same, that concrete type. diff --git a/alib2std/test-src/extensions/container/VariantTest.cpp b/alib2std/test-src/extensions/container/VariantTest.cpp index 8fea1b358f..4c09114f49 100644 --- a/alib2std/test-src/extensions/container/VariantTest.cpp +++ b/alib2std/test-src/extensions/container/VariantTest.cpp @@ -18,6 +18,8 @@ void VariantTest::testVariant() { ext::variant<int, std::string, VariantTest::test> d(10); CPPUNIT_ASSERT( d.is<int>() ); CPPUNIT_ASSERT( d.get<int>() == 10 ); + CPPUNIT_ASSERT( d == 10 ); + CPPUNIT_ASSERT( 10 == d ); std::string str = "abcde"; d.set<std::string>(str); -- GitLab