From c5828e622760e4a2569a762983eb868b97f24acf Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 24 Jan 2019 14:12:59 +0100 Subject: [PATCH] fix binding scheme of qualified values --- .../abstraction/ValueOperationAbstraction.hpp | 128 +++++++++++++++++- .../src/abstraction/ValueProvider.hpp | 23 +++- 2 files changed, 143 insertions(+), 8 deletions(-) diff --git a/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp b/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp index 8a022b6847..d2787e679c 100644 --- a/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp +++ b/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp @@ -25,6 +25,70 @@ class UnspecifiedType { template < class ReturnType > class ValueOperationAbstraction : public OperationAbstraction, public ValueProvider < ReturnType >, public ValueProvider < ReturnType & >, public ValueProvider < const ReturnType & >, public ValueProvider < ReturnType && >, public ValueProvider < const ReturnType && > { protected: + virtual bool isConst ( ) const override { + return false; + } + + virtual bool isRvalueRef ( ) const override { + return false; + } + + virtual bool isLvalueRef ( ) const override { + return false; + } + + virtual ReturnType & getData ( ) const override { + return m_data.value ( ); + } + + virtual const ReturnType & getConstData ( ) const override { + return m_data.value ( ); + } + + mutable std::optional < ReturnType > m_data; + +public: + template < typename ... ParamTypes, typename Callable > + inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) { + if ( ! cached ( ) ) + m_data = abstraction::apply < ParamTypes ... > ( callback, inputs ); + } + + virtual ext::type_index getReturnTypeIndex ( ) const override { + return ext::type_index ( typeid ( ReturnType ) ); + } + + virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override { + if ( cached ( ) ) + return ext::type_index ( typeid ( getData ( ) ) ); + else + throw std::domain_error ( "Runtime type unknown before evaluation." ); + } + + virtual bool cached ( ) const override { + return ( bool ) m_data; + } + + virtual void reset ( ) override { + m_data.reset ( ); + } +}; + +template < class ReturnType > +class ValueOperationAbstraction < const ReturnType > : public OperationAbstraction, public ValueProvider < ReturnType >, public ValueProvider < const ReturnType & >, public ValueProvider < const ReturnType && > { +protected: + virtual bool isConst ( ) const override { + return true; + } + + virtual bool isRvalueRef ( ) const override { + return false; + } + + virtual bool isLvalueRef ( ) const override { + return false; + } + virtual ReturnType & getData ( ) const override { return m_data.value ( ); } @@ -63,8 +127,20 @@ public: }; template < class ReturnType > -class ValueOperationAbstraction < ReturnType & > : public OperationAbstraction, public ValueProvider < ReturnType & >, public ValueProvider < const ReturnType & >, public ValueProvider < ReturnType && >, public ValueProvider < const ReturnType && > { +class ValueOperationAbstraction < ReturnType & > : public OperationAbstraction, public ValueProvider < ReturnType >, public ValueProvider < ReturnType & >, public ValueProvider < const ReturnType & >, public ValueProvider < ReturnType && >, public ValueProvider < const ReturnType && > { protected: + virtual bool isConst ( ) const override { + return false; + } + + virtual bool isRvalueRef ( ) const override { + return true; + } + + virtual bool isLvalueRef ( ) const override { + return false; + } + virtual ReturnType & getData ( ) const override { return m_data->get ( ); } @@ -103,8 +179,24 @@ public: }; template < class ReturnType > -class ValueOperationAbstraction < const ReturnType & > : public OperationAbstraction, public ValueProvider < const ReturnType & >, public ValueProvider < const ReturnType && > { +class ValueOperationAbstraction < const ReturnType & > : public OperationAbstraction, public ValueProvider < ReturnType >, public ValueProvider < const ReturnType & >, public ValueProvider < const ReturnType && > { protected: + virtual bool isConst ( ) const override { + return true; + } + + virtual bool isRvalueRef ( ) const override { + return true; + } + + virtual bool isLvalueRef ( ) const override { + return false; + } + + virtual ReturnType & getData ( ) const override { + return const_cast < ReturnType & > ( m_data->get ( ) ); + } + virtual const ReturnType & getConstData ( ) const override { return m_data->get ( ); } @@ -139,8 +231,20 @@ public: }; template < class ReturnType > -class ValueOperationAbstraction < ReturnType && > : public OperationAbstraction, public ValueProvider < ReturnType & >, public ValueProvider < const ReturnType & >, public ValueProvider < ReturnType && >, public ValueProvider < const ReturnType && > { +class ValueOperationAbstraction < ReturnType && > : public OperationAbstraction, public ValueProvider < ReturnType >, public ValueProvider < const ReturnType & >, public ValueProvider < ReturnType && >, public ValueProvider < const ReturnType && > { protected: + virtual bool isConst ( ) const override { + return false; + } + + virtual bool isRvalueRef ( ) const override { + return false; + } + + virtual bool isLvalueRef ( ) const override { + return true; + } + virtual ReturnType & getData ( ) const override { return m_data->get ( ); } @@ -181,8 +285,24 @@ public: }; template < class ReturnType > -class ValueOperationAbstraction < const ReturnType && > : public OperationAbstraction, public ValueProvider < const ReturnType & >, public ValueProvider < const ReturnType && > { +class ValueOperationAbstraction < const ReturnType && > : public OperationAbstraction, public ValueProvider < ReturnType >, public ValueProvider < const ReturnType & >, public ValueProvider < const ReturnType && > { protected: + virtual bool isConst ( ) const override { + return true; + } + + virtual bool isRvalueRef ( ) const override { + return false; + } + + virtual bool isLvalueRef ( ) const override { + return true; + } + + virtual ReturnType & getData ( ) const override { + return const_cast < ReturnType & > ( m_data->get ( ) ); + } + virtual const ReturnType & getConstData ( ) const override { return m_data->get ( ); } diff --git a/alib2abstraction/src/abstraction/ValueProvider.hpp b/alib2abstraction/src/abstraction/ValueProvider.hpp index 5966731609..56f77de7ee 100644 --- a/alib2abstraction/src/abstraction/ValueProvider.hpp +++ b/alib2abstraction/src/abstraction/ValueProvider.hpp @@ -17,12 +17,15 @@ namespace abstraction { template < class Type > class ValueProvider { protected: + virtual bool isConst ( ) const = 0; + virtual bool isLvalueRef ( ) const = 0; + virtual bool isRvalueRef ( ) const = 0; virtual Type & getData ( ) const = 0; public: template < class T = Type > typename std::enable_if < std::is_copy_constructible < T >::value && std::is_move_constructible < T >::value, T >::type getValue ( bool move ) const { - if ( move ) + if ( ! isConst ( ) && move ) return std::move ( getData ( ) ); else return getData ( ); @@ -30,7 +33,7 @@ public: template < class T = Type > typename std::enable_if < std::is_copy_constructible < T >::value && ! std::is_move_constructible < T >::value, T >::type getValue ( bool move ) const { - if ( move ) + if ( ! isConst ( ) && move ) throw std::domain_error ( "Value not move constructible" ); else return getData ( ); @@ -38,7 +41,7 @@ public: template < class T = Type > typename std::enable_if < ! std::is_copy_constructible < T >::value && std::is_move_constructible < T >::value, T >::type getValue ( bool move ) const { - if ( move ) + if ( ! isConst ( ) && move ) return std::move ( getData ( ) ); else throw std::domain_error ( "Value not copy constructible" ); @@ -46,7 +49,7 @@ public: template < class T = Type > typename std::enable_if < ! std::is_copy_constructible < T >::value && ! std::is_move_constructible < T >::value, T >::type getValue ( bool move ) const { - if ( move ) + if ( ! isConst ( ) && move ) throw std::domain_error ( "Value not move constructible" ); else throw std::domain_error ( "Value not copy constructible" ); @@ -58,6 +61,9 @@ public: template < class Type > class ValueProvider < Type & > { protected: + virtual bool isConst ( ) const = 0; + virtual bool isLvalueRef ( ) const = 0; + virtual bool isRvalueRef ( ) const = 0; virtual Type & getData ( ) const = 0; public: @@ -75,6 +81,9 @@ public: template < class Type > class ValueProvider < const Type & > { protected: + virtual bool isConst ( ) const = 0; + virtual bool isLvalueRef ( ) const = 0; + virtual bool isRvalueRef ( ) const = 0; virtual const Type & getConstData ( ) const = 0; public: @@ -92,6 +101,9 @@ public: template < class Type > class ValueProvider < Type && > { protected: + virtual bool isConst ( ) const = 0; + virtual bool isLvalueRef ( ) const = 0; + virtual bool isRvalueRef ( ) const = 0; virtual Type & getData ( ) const = 0; public: @@ -112,6 +124,9 @@ public: template < class Type > class ValueProvider < const Type && > { protected: + virtual bool isConst ( ) const = 0; + virtual bool isLvalueRef ( ) const = 0; + virtual bool isRvalueRef ( ) const = 0; virtual const Type & getConstData ( ) const = 0; public: -- GitLab