From 2d5e1c3a2910f7e68d3a915d927e235ed76af766 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 4 Jul 2017 22:28:29 +0200 Subject: [PATCH] new algorithm, cast, type abstraction --- .../src/abstraction/AlgorithmAbstraction.hpp | 175 ++++++++++++++++++ .../src/abstraction/AlgorithmRegistry.hpp | 125 +++++++++++++ .../src/abstraction/CastAbstraction.hpp | 37 ++++ alib2common/src/abstraction/CastRegistry.hpp | 108 +++++++++++ .../src/abstraction/DowncastAbstraction.hpp | 37 ++++ .../src/abstraction/DowncastRegistry.hpp | 71 +++++++ .../src/abstraction/ImmediateRegistry.hpp | 77 ++++++++ .../abstraction/ImmediateValueAbstraction.hpp | 30 +++ .../src/abstraction/NormalizeAbstraction.hpp | 37 ++++ .../src/abstraction/NormalizeRegistry.hpp | 74 ++++++++ .../NullaryOperationAbstraction.hpp | 60 ++++++ .../src/abstraction/OperationAbstraction.hpp | 51 +++++ .../src/abstraction/PrimitiveRegistrator.cpp | 54 ++++++ alib2common/src/abstraction/Registry.cpp | 57 ++++++ alib2common/src/abstraction/Registry.h | 31 ++++ .../src/abstraction/ResultClassSelector.hpp | 29 +++ .../abstraction/UnaryOperationAbstraction.hpp | 91 +++++++++ .../abstraction/ValueOperationAbstraction.hpp | 91 +++++++++ .../abstraction/ValuePrinterAbstraction.hpp | 33 ++++ .../src/abstraction/ValuePrinterRegistry.hpp | 74 ++++++++ .../abstraction/VoidOperationAbstraction.hpp | 63 +++++++ .../abstraction/XmlFileWriterAbstraction.hpp | 35 ++++ .../src/abstraction/XmlFileWriterRegistry.hpp | 75 ++++++++ .../src/abstraction/XmlParserAbstraction.hpp | 36 ++++ .../src/abstraction/XmlParserRegistry.hpp | 70 +++++++ 25 files changed, 1621 insertions(+) create mode 100644 alib2common/src/abstraction/AlgorithmAbstraction.hpp create mode 100644 alib2common/src/abstraction/AlgorithmRegistry.hpp create mode 100644 alib2common/src/abstraction/CastAbstraction.hpp create mode 100644 alib2common/src/abstraction/CastRegistry.hpp create mode 100644 alib2common/src/abstraction/DowncastAbstraction.hpp create mode 100644 alib2common/src/abstraction/DowncastRegistry.hpp create mode 100644 alib2common/src/abstraction/ImmediateRegistry.hpp create mode 100644 alib2common/src/abstraction/ImmediateValueAbstraction.hpp create mode 100644 alib2common/src/abstraction/NormalizeAbstraction.hpp create mode 100644 alib2common/src/abstraction/NormalizeRegistry.hpp create mode 100644 alib2common/src/abstraction/NullaryOperationAbstraction.hpp create mode 100644 alib2common/src/abstraction/OperationAbstraction.hpp create mode 100644 alib2common/src/abstraction/PrimitiveRegistrator.cpp create mode 100644 alib2common/src/abstraction/Registry.cpp create mode 100644 alib2common/src/abstraction/Registry.h create mode 100644 alib2common/src/abstraction/ResultClassSelector.hpp create mode 100644 alib2common/src/abstraction/UnaryOperationAbstraction.hpp create mode 100644 alib2common/src/abstraction/ValueOperationAbstraction.hpp create mode 100644 alib2common/src/abstraction/ValuePrinterAbstraction.hpp create mode 100644 alib2common/src/abstraction/ValuePrinterRegistry.hpp create mode 100644 alib2common/src/abstraction/VoidOperationAbstraction.hpp create mode 100644 alib2common/src/abstraction/XmlFileWriterAbstraction.hpp create mode 100644 alib2common/src/abstraction/XmlFileWriterRegistry.hpp create mode 100644 alib2common/src/abstraction/XmlParserAbstraction.hpp create mode 100644 alib2common/src/abstraction/XmlParserRegistry.hpp diff --git a/alib2common/src/abstraction/AlgorithmAbstraction.hpp b/alib2common/src/abstraction/AlgorithmAbstraction.hpp new file mode 100644 index 0000000000..273789b692 --- /dev/null +++ b/alib2common/src/abstraction/AlgorithmAbstraction.hpp @@ -0,0 +1,175 @@ +/* + * AlgorithmAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _ALGORITHM_ABSTRACTION_HPP_ +#define _ALGORITHM_ABSTRACTION_HPP_ + +#include <abstraction/ResultClassSelector.hpp> +#include <tuple> +#include <memory> +#include <abstraction/Registry.h> + +namespace abstraction { + +template < class ReturnType, class ... ParamTypes > +class Callback { + std::function < ReturnType ( ParamTypes ... ) > m_callback; + +public: + Callback ( std::function < ReturnType ( ParamTypes ... ) > callback ) : m_callback ( callback ) { + } + + ReturnType * operator ( ) ( ParamTypes ... params ) { + return new ReturnType ( m_callback ( std::forward < ParamTypes > ( params ) ... ) ); + } +}; + +template < class ReturnType, class ... ParamTypes > +class Callback < ReturnType *, ParamTypes ... > { + std::function < ReturnType * ( ParamTypes ... ) > m_callback; + +public: + Callback ( std::function < ReturnType * ( ParamTypes ... ) > callback ) : m_callback ( callback ) { + } + + ReturnType * operator ( ) ( ParamTypes ... params ) { + return m_callback ( std::forward < ParamTypes > ( params ) ... ); + } +}; + +template < class ReturnType, class ... ParamTypes > +class AlgorithmAbstractionBase : public ResultClassSelector < ReturnType >::OutputClass { +protected: + std::tuple < std::shared_ptr < ValueOperationAbstraction < typename std::decay < ParamTypes >::type > > ... > inputs; + + virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index ) override { + auto attachCallback = [ & ] ( auto & param ) { + if ( param != nullptr ) + return false; + + typename std::decay < decltype ( param )>::type validData = std::dynamic_pointer_cast < typename std::decay < decltype ( param ) >::type::element_type > ( input ); + if ( validData ) { + param = validData; + return true; + } else { + return false; + } + }; + return std::call_on_nth < bool > ( inputs, index, attachCallback ); + } + + virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & input ) override { + bool res = false; + std::foreach ( inputs, [ & ] ( auto & param ) { + if ( param == input ) { + param = nullptr; + res = true; + } + } ); + return res; + } + +public: + virtual bool inputsReady ( ) const override { + auto readyCallback = [ ] ( const auto & param ) { + return ( bool ) param && param->isReady ( ); + }; + + return all_of ( inputs, readyCallback ); + } + + virtual bool inputsAttached ( ) const override { + auto attachedCallback = [ ] ( const auto & param ) { + return ( bool ) param; + }; + + return all_of ( inputs, attachedCallback ); + } + + virtual bool eval ( ) override { + if ( ! inputsAttached ( ) ) + return false; + + if ( this->cached ( ) ) + return true; + + auto evalCallback = [ ] ( const auto & param ) { + return param->eval ( ); + }; + + if ( ! all_of ( inputs, evalCallback ) ) + return false; + + return this->run ( ); + } + + virtual unsigned numberOfParams ( ) const override { + return sizeof ... ( ParamTypes ); + } + + virtual std::shared_ptr < OperationAbstraction > getImmediateValueFromParam ( unsigned index, const std::string & value ) const override { + auto callback = [ & ] ( auto & param ) { + std::string paramType = std::type_name < typename std::decay < decltype ( param ) >::type::element_type::return_type > ( ); + return Registry::getImmediateAbstraction ( std::move ( paramType ), value ); + }; + return std::call_on_nth < std::shared_ptr < OperationAbstraction > > ( inputs, index, callback ); + } + + virtual std::shared_ptr < OperationAbstraction > getXmlParserFromParam ( unsigned index, std::deque < sax::Token > tokens ) const override { + auto callback = [ & ] ( auto & param ) { + std::string paramType = std::type_name < typename std::decay < decltype ( param ) >::type::element_type::return_type > ( ); + return Registry::getXmlParserAbstraction ( std::move ( paramType ), std::move ( tokens ) ); + }; + return std::call_on_nth < std::shared_ptr < OperationAbstraction > > ( inputs, index, callback ); + } +}; + +template < class ReturnType, class ... ParamTypes > +class AlgorithmAbstraction : public AlgorithmAbstractionBase < ReturnType, ParamTypes ... > { + Callback < ReturnType, ParamTypes ... > m_callback; + +public: + AlgorithmAbstraction ( std::function < ReturnType ( ParamTypes ... ) > callback ) : m_callback ( callback ) { + } + + virtual bool run ( ) override { + if ( ! this->inputsReady ( ) ) + return false; + + if ( this->cached ( ) ) + return true; + + this->run_helper ( m_callback, this->inputs, std::make_index_sequence < sizeof ... ( ParamTypes ) > { } ); + return true; + } + +}; + +template < class ReturnType, class ... ParamTypes > +class AlgorithmAbstraction < ReturnType *, ParamTypes ... > : public AlgorithmAbstractionBase < ReturnType, ParamTypes ... > { + Callback < ReturnType *, ParamTypes ... > m_callback; + +public: + AlgorithmAbstraction ( std::function < ReturnType * ( ParamTypes ... ) > callback ) : m_callback ( callback ) { + } + + virtual bool run ( ) override { + if ( ! this->inputsReady ( ) ) + return false; + + if ( this->cached ( ) ) + return true; + + this->run_helper ( m_callback, this->inputs, std::make_index_sequence < sizeof ... ( ParamTypes ) > { } ); + return true; + } + +}; + +} /* namespace abstraction */ + +#endif /* _ALGORITHM_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/AlgorithmRegistry.hpp b/alib2common/src/abstraction/AlgorithmRegistry.hpp new file mode 100644 index 0000000000..79d6b70075 --- /dev/null +++ b/alib2common/src/abstraction/AlgorithmRegistry.hpp @@ -0,0 +1,125 @@ +/* + * AlgorithmRegistry.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _ALGORITHM_REGISTRY_HPP_ +#define _ALGORITHM_REGISTRY_HPP_ + +#include <functional> +#include <memory> +#include <vector> +#include <string> + +#include <exception/CommonException.h> +#include <abstraction/OperationAbstraction.hpp> + +namespace abstraction { + +class AlgorithmRegistry { + class Entry { + bool m_downcast; + bool m_normalize; + + public: + Entry ( bool downcast, bool normalize ) : m_downcast ( downcast ), m_normalize ( normalize ) { + + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0; + + bool getDowncast ( ) const { + return m_downcast; + } + + bool getNormalize ( ) const { + return m_normalize; + } + }; + + template < class Return, class ... Params > + class EntryImpl : public Entry { + std::function < Return ( Params ... ) > m_callback; + + public: + EntryImpl ( std::function < Return ( Params ... ) > callback, bool downcast, bool normalize ) : Entry ( downcast, normalize ), m_callback ( callback ) { + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override; + }; + + template < class Return, class ... Params > + class EntryImpl < Return *, Params ... > : public Entry { + std::function < Return * ( Params ... ) > m_callback; + + public: + EntryImpl ( std::function < Return * ( Params ... ) > callback, bool downcast, bool normalize ) : Entry ( downcast, normalize ), m_callback ( callback ) { + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override; + }; + + static std::map < std::string, std::map < std::vector < std::type_index >, std::unique_ptr < Entry > > > & getEntries ( ) { + static std::map < std::string, std::map < std::vector < std::type_index >, std::unique_ptr < Entry > > > algorithmGroups; + return algorithmGroups; + }; + +public: + template < class Algo, class ReturnType, class ... ParamTypes > + static void registerAlgorithm ( ReturnType ( * callback ) ( ParamTypes ... ), bool downcast, bool normalize ) { + std::string algorithm = std::type_name < Algo > ( ); + + std::vector < std::type_index > params; + ( void ) std::initializer_list < int > { ( params.push_back ( std::type_index ( typeid ( typename std::decay < ParamTypes >::type ) ) ), 0 ) ... }; + + if ( ! getEntries ( ) [ algorithm ].insert ( std::make_pair ( params, std::unique_ptr < Entry > ( new EntryImpl < ReturnType, ParamTypes ... > ( callback, downcast, normalize ) ) ) ).second ) + throw ::exception::CommonException ( "Callback for " + algorithm + " already registered." ); + } + + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes, bool & downcast, bool & normalize ) { + auto group = getEntries ( ).find ( name ); + if ( group == getEntries ( ).end ( ) ) + throw exception::CommonException ( "Entry " + name + " not available" ); + + auto overload = group->second.find ( paramTypes ); + if ( overload == group->second.end ( ) ) { + std::stringstream ss; + ss << paramTypes; + + throw exception::CommonException ( "Entry overload " + ss.str ( ) + " not available" ); + } + + downcast = overload->second->getDowncast ( ); + normalize = overload->second->getNormalize ( ); + + return overload->second->getAbstraction ( ); + } + + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes ) { + bool downcast; + bool normalize; + return getAbstraction ( std::move ( name ), paramTypes, downcast, normalize ); + } +}; + +} /* namespace abstraction */ + +#include <abstraction/AlgorithmAbstraction.hpp> + +namespace abstraction { + +template < class Return, class ... Params > +std::shared_ptr < abstraction::OperationAbstraction > AlgorithmRegistry::EntryImpl < Return, Params ... >::getAbstraction ( ) const { + return std::make_shared < abstraction::AlgorithmAbstraction < Return, Params ... > > ( m_callback ); +} + +template < class Return, class ... Params > +std::shared_ptr < abstraction::OperationAbstraction > AlgorithmRegistry::EntryImpl < Return *, Params ... >::getAbstraction ( ) const { + return std::make_shared < abstraction::AlgorithmAbstraction < Return *, Params ... > > ( m_callback ); +} + +} /* namespace abstraction */ + +#endif /* _ALGORITHM_REGISTRY_HPP_ */ diff --git a/alib2common/src/abstraction/CastAbstraction.hpp b/alib2common/src/abstraction/CastAbstraction.hpp new file mode 100644 index 0000000000..87ce0eb5cb --- /dev/null +++ b/alib2common/src/abstraction/CastAbstraction.hpp @@ -0,0 +1,37 @@ +/* + * CastAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _CAST_ABSTRACTION_HPP_ +#define _CAST_ABSTRACTION_HPP_ + +#include <abstraction/UnaryOperationAbstraction.hpp> +#include <tuple> + +namespace abstraction { + +template < class ReturnType, class ParamType > +class CastAbstraction : public UnaryOperationAbstraction < ReturnType, ParamType > { +public: + CastAbstraction ( ) { + } + + virtual bool run ( ) override { + if ( ! this->inputsReady ( ) ) + return false; + + if ( this->cached ( ) ) + return true; + + this->m_data = std::unique_ptr < ReturnType > ( new ReturnType ( this->m_param->getData ( ) ) ); + + return true; + } +}; + +} /* namespace abstraction */ + +#endif /* _CAST_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/CastRegistry.hpp b/alib2common/src/abstraction/CastRegistry.hpp new file mode 100644 index 0000000000..f365c635a6 --- /dev/null +++ b/alib2common/src/abstraction/CastRegistry.hpp @@ -0,0 +1,108 @@ +/* + * CastRegistry.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _CAST_REGISTRY_HPP_ +#define _CAST_REGISTRY_HPP_ + +#include <memory> +#include <string> + +#include <exception/CommonException.h> +#include <abstraction/OperationAbstraction.hpp> + +namespace abstraction { + +class CastRegistry { + class Entry { + public: + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0; + + }; + + template < class Return, class Param > + class DefaultEntryImpl : public Entry { + public: + DefaultEntryImpl ( ) { + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override; + }; + + template < class Return, class Param > + class AlgorithmEntryImpl : public Entry { + std::function < Return ( Param ) > m_callback; + public: + AlgorithmEntryImpl ( std::function < Return ( Param ) > callback ) : m_callback ( callback ) { + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override; + }; + + static std::map < std::pair < std::string, std::string >, std::unique_ptr < Entry > > & getEntries ( ) { + static std::map < std::pair < std::string, std::string >, std::unique_ptr < Entry > > casts; + return casts; + }; + +public: + template < class TargetType, class ParamType > + static void registerCast ( std::string target, std::string param ) { + if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( target, param ), std::unique_ptr < Entry > ( new DefaultEntryImpl < TargetType, ParamType > ( ) ) ) ).second ) + throw ::exception::CommonException ( "Entry from " + param + " to " + target + " already registered." ); + } + + template < class TargetType, class ParamType > + static void registerCast ( ) { + std::string target = std::type_name < TargetType > ( ); + std::string param = std::type_name < ParamType > ( ); + + registerCast < TargetType, ParamType > ( target, param ); + } + + template < class TargetType, class ParamType > + static void registerCastAlgorithm ( std::string target, std::string param, TargetType ( * callback ) ( ParamType ) ) { + if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( target, param ), std::unique_ptr < Entry > ( new AlgorithmEntryImpl < TargetType, ParamType > ( callback ) ) ) ).second ) + throw ::exception::CommonException ( "Entry from " + param + " to " + target + " already registered." ); + } + + template < class TargetType, class ParamType > + static void registerCastAlgorithm ( TargetType ( * callback ) ( ParamType ) ) { + std::string target = std::type_name < TargetType > ( ); + std::string param = std::type_name < ParamType > ( ); + + registerCastAlgorithm < TargetType, ParamType > ( target, param, callback ); + } + + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string target, std::string param ) { + auto cast = getEntries ( ).find ( std::make_pair ( target, param ) ); + if ( cast == getEntries ( ).end ( ) ) + throw exception::CommonException ( "Entry from " + param + " to " + target + " not available." ); + + return cast->second->getAbstraction ( ); + } + +}; + +} /* namespace abstraction */ + +#include <abstraction/CastAbstraction.hpp> +#include <abstraction/AlgorithmAbstraction.hpp> + +namespace abstraction { + +template < class Return, class Param > +std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::DefaultEntryImpl < Return, Param >::getAbstraction ( ) const { + return std::make_shared < abstraction::CastAbstraction < Return, Param > > ( ); +} + +template < class Return, class Param > +std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::AlgorithmEntryImpl < Return, Param >::getAbstraction ( ) const { + return std::make_shared < abstraction::AlgorithmAbstraction < Return, Param > > ( m_callback ); +} + +} /* namespace abstraction */ + +#endif /* _CAST_REGISTRY_HPP_ */ diff --git a/alib2common/src/abstraction/DowncastAbstraction.hpp b/alib2common/src/abstraction/DowncastAbstraction.hpp new file mode 100644 index 0000000000..71504db528 --- /dev/null +++ b/alib2common/src/abstraction/DowncastAbstraction.hpp @@ -0,0 +1,37 @@ +/* + * DowncastAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _DOWNCAST_ABSTRACTION_HPP_ +#define _DOWNCAST_ABSTRACTION_HPP_ + +#include <abstraction/UnaryOperationAbstraction.hpp> +#include <memory> + +namespace abstraction { + +template < class ConcreteType, class BaseType > +class DowncastAbstraction : public UnaryOperationAbstraction < ConcreteType, BaseType > { +public: + DowncastAbstraction ( ) { + } + + virtual bool run ( ) override { + if ( ! this->inputsReady ( ) ) + return false; + + if ( this->cached ( ) ) + return true; + + this->m_data = std::unique_ptr < ConcreteType > ( static_cast < ConcreteType * > ( this->m_param->getData ( ).clone ( ) ) ); + + return true; + } +}; + +} /* namespace abstraction */ + +#endif /* _DOWNCAST_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/DowncastRegistry.hpp b/alib2common/src/abstraction/DowncastRegistry.hpp new file mode 100644 index 0000000000..223fe6ced4 --- /dev/null +++ b/alib2common/src/abstraction/DowncastRegistry.hpp @@ -0,0 +1,71 @@ +/* + * DowncastRegistry.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _DOWNCAST_REGISTRY_HPP_ +#define _DOWNCAST_REGISTRY_HPP_ + +#include <memory> +#include <string> + +#include <exception/CommonException.h> +#include <abstraction/OperationAbstraction.hpp> + +namespace abstraction { + +class DowncastRegistry { + class Entry { + public: + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0; + + }; + + template < class ConcreteType, class BaseType > + class EntryImpl : public Entry { + public: + EntryImpl ( ) { + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override; + }; + + static std::map < std::pair < std::string, std::string >, std::unique_ptr < Entry > > & getEntries ( ) { + static std::map < std::pair < std::string, std::string >, std::unique_ptr < Entry > > fileWriters; + return fileWriters; + } + +public: + template < class ConcreteType, class BaseType > + static void registerDowncast ( ) { + std::string concrete = std::type_name < ConcreteType > ( ); + std::string base = std::type_name < BaseType > ( ); + if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( concrete, base ), std::unique_ptr < Entry > ( new EntryImpl < ConcreteType, BaseType > ( ) ) ) ).second ) + throw ::exception::CommonException ( "Downcasting for " + base + " to " + concrete + " already registered." ); + } + + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string concrete, std::string base ) { + auto res = getEntries ( ).find ( std::make_pair ( concrete, base ) ); + if ( res == getEntries ( ).end ( ) ) + throw exception::CommonException ( "Entry " + concrete + ", " + base + " not available." ); + + return res->second->getAbstraction ( ); + } +}; + +} /* namespace abstraction */ + +#include <abstraction/DowncastAbstraction.hpp> + +namespace abstraction { + +template < class ConcreteType, class BaseType > +std::shared_ptr < abstraction::OperationAbstraction > DowncastRegistry::EntryImpl < ConcreteType, BaseType >::getAbstraction ( ) const { + return std::make_shared < DowncastAbstraction < ConcreteType, BaseType > > ( ); +} + +} /* namespace abstraction */ + +#endif /* _DOWNCAST_REGISTRY_HPP_ */ diff --git a/alib2common/src/abstraction/ImmediateRegistry.hpp b/alib2common/src/abstraction/ImmediateRegistry.hpp new file mode 100644 index 0000000000..2a63eb4f6f --- /dev/null +++ b/alib2common/src/abstraction/ImmediateRegistry.hpp @@ -0,0 +1,77 @@ +/* + * ImmediateRegistry.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _IMMEDIATE_REGISTRY_HPP_ +#define _IMMEDIATE_REGISTRY_HPP_ + +#include <factory/XmlDataFactory.hpp> + +#include <memory> +#include <string> + +#include <exception/CommonException.h> +#include <abstraction/OperationAbstraction.hpp> + +namespace abstraction { + +class ImmediateRegistry { + class Entry { + public: + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string value ) const = 0; + + }; + + template < class Result > + class EntryImpl : public Entry { + public: + EntryImpl ( ) { + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string value ) const override; + }; + + static std::map < std::string, std::unique_ptr < Entry > > & getEntries ( ) { + static std::map < std::string, std::unique_ptr < Entry > > fileWriters; + return fileWriters; + } + +public: + template < class ResultType > + static void registerImmediate ( std::string result ) { + if ( ! getEntries ( ).insert ( std::make_pair ( result, std::unique_ptr < Entry > ( new EntryImpl < ResultType > ( ) ) ) ).second ) + throw ::exception::CommonException ( "Entry " + result + " already registered." ); + } + + template < class ResultType > + static void registerImmediate ( ) { + std::string result = std::type_name < ResultType > ( ); + registerImmediate < ResultType > ( std::move ( result ) ); + } + + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string result, std::string value ) { + auto res = getEntries ( ).find ( result ); + if ( res == getEntries ( ).end ( ) ) + throw exception::CommonException ( "Entry " + result + " not available." ); + + return res->second->getAbstraction ( value ); + } +}; + +} /* namespace abstraction */ + +#include <abstraction/ImmediateValueAbstraction.hpp> + +namespace abstraction { + +template < class Result > +std::shared_ptr < abstraction::OperationAbstraction > ImmediateRegistry::EntryImpl < Result >::getAbstraction ( std::string value ) const { + return std::make_shared < ImmediateValueAbstraction < Result > > ( std::from_string < Result > ( value ) ); +} + +} /* namespace abstraction */ + +#endif /* _IMMEDIATE_REGISTRY_HPP_ */ diff --git a/alib2common/src/abstraction/ImmediateValueAbstraction.hpp b/alib2common/src/abstraction/ImmediateValueAbstraction.hpp new file mode 100644 index 0000000000..286c7947b0 --- /dev/null +++ b/alib2common/src/abstraction/ImmediateValueAbstraction.hpp @@ -0,0 +1,30 @@ +/* + * ImmediateValueAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _IMMEDIATE_VALUE_ABSTRACTION_HPP_ +#define _IMMEDIATE_VALUE_ABSTRACTION_HPP_ + +#include <abstraction/NullaryOperationAbstraction.hpp> +#include <tuple> + +namespace abstraction { + +template < class ReturnType > +class ImmediateValueAbstraction : public NullaryOperationAbstraction < ReturnType > { +public: + ImmediateValueAbstraction ( ReturnType result ) { + this->m_data = std::unique_ptr < ReturnType > ( new ReturnType ( result ) ); + } + + virtual bool run ( ) override { + return true; + } +}; + +} /* namespace abstraction */ + +#endif /* _IMMEDIATE_VALUE_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/NormalizeAbstraction.hpp b/alib2common/src/abstraction/NormalizeAbstraction.hpp new file mode 100644 index 0000000000..a0aa378852 --- /dev/null +++ b/alib2common/src/abstraction/NormalizeAbstraction.hpp @@ -0,0 +1,37 @@ +/* + * NormalizeAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _NORMALIZE_ABSTRACTION_HPP_ +#define _NORMALIZE_ABSTRACTION_HPP_ + +#include <abstraction/UnaryOperationAbstraction.hpp> +#include <tuple> + +namespace abstraction { + +template < class ReturnType, class ParamType > +class NormalizeAbstraction : public UnaryOperationAbstraction < ReturnType, ParamType > { +public: + NormalizeAbstraction ( ) { + } + + virtual bool run ( ) override { + if ( ! this->inputsReady ( ) ) + return false; + + if ( this->cached ( ) ) + return true; + + this->m_data = std::unique_ptr < ReturnType > ( ( ReturnType * ) std::move ( this->m_param->getData ( ) ).normalize ( ) ); + + return true; + } +}; + +} /* namespace abstraction */ + +#endif /* _NORMALIZE_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/NormalizeRegistry.hpp b/alib2common/src/abstraction/NormalizeRegistry.hpp new file mode 100644 index 0000000000..45d4429f5f --- /dev/null +++ b/alib2common/src/abstraction/NormalizeRegistry.hpp @@ -0,0 +1,74 @@ +/* + * NormalizeRegistry.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _NORMALIZE_REGISTRY_HPP_ +#define _NORMALIZE_REGISTRY_HPP_ + +#include <memory> +#include <string> + +#include <exception/CommonException.h> +#include <abstraction/OperationAbstraction.hpp> + +namespace abstraction { + +class NormalizeRegistry { + class Entry { + public: + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0; + + }; + + template < class Param > + class EntryImpl : public Entry { + public: + EntryImpl ( ) { + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override; + }; + + static std::map < std::string, std::unique_ptr < Entry > > & getEntries ( ) { + static std::map < std::string, std::unique_ptr < Entry > > fileWriters; + return fileWriters; + } + +public: + template < class ParamType > + static void registerNormalize ( std::string param ) { + getEntries ( ).insert ( std::make_pair ( param, std::unique_ptr < Entry > ( new EntryImpl < ParamType > ( ) ) ) ); + } + + template < class ParamType > + static void registerNormalize ( ) { + std::string param = std::type_name < ParamType > ( ); + registerNormalize < ParamType > ( std::move ( param ) ); + } + + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string param ) { + auto res = getEntries ( ).find ( param ); + if ( res == getEntries ( ).end ( ) ) + throw exception::CommonException ( "Entry " + param + " not available." ); + + return res->second->getAbstraction ( ); + } +}; + +} /* namespace abstraction */ + +#include <abstraction/NormalizeAbstraction.hpp> + +namespace abstraction { + +template < class Param > +std::shared_ptr < abstraction::OperationAbstraction > NormalizeRegistry::EntryImpl < Param >::getAbstraction ( ) const { + return std::make_shared < NormalizeAbstraction < typename Param::normalized_type, Param > > ( ); +} + +} /* namespace abstraction */ + +#endif /* _NORMALIZE_REGISTRY_HPP_ */ diff --git a/alib2common/src/abstraction/NullaryOperationAbstraction.hpp b/alib2common/src/abstraction/NullaryOperationAbstraction.hpp new file mode 100644 index 0000000000..9885926381 --- /dev/null +++ b/alib2common/src/abstraction/NullaryOperationAbstraction.hpp @@ -0,0 +1,60 @@ +/* + * NullaryOperationAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _NULLARY_OPERATION_ABSTRACTION_HPP_ +#define _NULLARY_OPERATION_ABSTRACTION_HPP_ + +#include <abstraction/ResultClassSelector.hpp> +#include <exception/CommonException.h> + +namespace abstraction { + +template < class ReturnType > +class NullaryOperationAbstraction : public ResultClassSelector < ReturnType >::OutputClass { + virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > &, unsigned ) override { + return false; + } + + virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & ) override { + return true; + } + +public: + NullaryOperationAbstraction ( ) { + } + + virtual bool inputsReady ( ) const override { + return true; + } + + virtual bool inputsAttached ( ) const override { + return true; + } + + virtual bool eval ( ) override { + if ( this->cached ( ) ) + return true; + + return this->run ( ); + } + + virtual unsigned numberOfParams ( ) const override { + return 0; + } + + virtual std::shared_ptr < OperationAbstraction > getImmediateValueFromParam ( unsigned, const std::string & ) const override { + throw exception::CommonException ( "Nullary algorithm does not have any parameter." ); + } + + virtual std::shared_ptr < OperationAbstraction > getXmlParserFromParam ( unsigned, std::deque < sax::Token > ) const override { + throw exception::CommonException ( "Nullary algorithm does not have any parameter." ); + } +}; + +} /* namespace abstraction */ + +#endif /* _NULLARY_OPERATION_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/OperationAbstraction.hpp b/alib2common/src/abstraction/OperationAbstraction.hpp new file mode 100644 index 0000000000..fbd76dab58 --- /dev/null +++ b/alib2common/src/abstraction/OperationAbstraction.hpp @@ -0,0 +1,51 @@ +/* + * OperationAbstraction.hpp + * + * Created on: 10. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _OPERATION_ABSTRACTION_HPP_ +#define _OPERATION_ABSTRACTION_HPP_ + +#include <memory> +#include <string> +#include <tuple> +#include <functional> + +#include <exception/CommonException.h> +#include <factory/XmlDataFactory.hpp> + +namespace abstraction { + +class OperationAbstraction : public std::enable_shared_from_this < OperationAbstraction > { +public: + virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index ) = 0; + virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & input ) = 0; + + virtual ~OperationAbstraction ( ) noexcept { + } + + virtual bool inputsReady ( ) const = 0; + virtual bool inputsAttached ( ) const = 0; + virtual bool run ( ) = 0; + virtual bool eval ( ) = 0; + virtual std::type_index type ( ) const = 0; + virtual std::type_index runtime_type ( ) const = 0; + virtual unsigned numberOfParams ( ) const = 0; + virtual bool cached ( ) const = 0; + + virtual std::shared_ptr < OperationAbstraction > getXmlParserFromParam ( unsigned index, std::deque < sax::Token > tokens ) const = 0; + virtual std::shared_ptr < OperationAbstraction > getImmediateValueFromParam ( unsigned index, const std::string & data ) const = 0; + + virtual std::shared_ptr < OperationAbstraction > getXmlFileWriterFromResult ( const std::string & filename ) const = 0; + virtual std::shared_ptr < OperationAbstraction > getValuePrinterFromResult ( ) const = 0; + virtual std::shared_ptr < OperationAbstraction > getCastFromResult ( const std::string & type ) const = 0; + virtual std::shared_ptr < OperationAbstraction > getNormalizeResult ( ) const = 0; + virtual std::shared_ptr < OperationAbstraction > getDowncastResult ( ) const = 0; + +}; + +} /* namespace abstraction */ + +#endif /* _OPERATION_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/PrimitiveRegistrator.cpp b/alib2common/src/abstraction/PrimitiveRegistrator.cpp new file mode 100644 index 0000000000..f8545dcee2 --- /dev/null +++ b/alib2common/src/abstraction/PrimitiveRegistrator.cpp @@ -0,0 +1,54 @@ +/* + * PrimitiveRegistrator.cpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#include "CastRegistry.hpp" +#include "XmlFileWriterRegistry.hpp" +#include "NormalizeRegistry.hpp" +#include "ValuePrinterRegistry.hpp" +#include "ImmediateRegistry.hpp" + +#include <primitive/Double.h> +#include <primitive/Integer.h> +#include <primitive/Bool.h> +#include <primitive/UnsignedLong.h> +#include <primitive/String.h> + +namespace abstraction { + +class PrimitiveCasts { +public: + PrimitiveCasts ( ) { + abstraction::CastRegistry::registerCast < double, int > ( ); + abstraction::CastRegistry::registerCast < int, double > ( ); + + abstraction::CastRegistry::registerCastAlgorithm < std::string, int > ( std::to_string ); + abstraction::CastRegistry::registerCastAlgorithm < int, std::string > ( (int(*)(std::string)) std::from_string < int > ); + + abstraction::CastRegistry::registerCast < bool, int > ( ); + + abstraction::CastRegistry::registerCast < size_t, int > ( "size_t", std::type_name < int > ( ) ); + abstraction::CastRegistry::registerCast < size_t, int > ( ); + abstraction::CastRegistry::registerCast < int, size_t > ( ); + + abstraction::CastRegistry::registerCast < int, primitive::Integer > ( ); + + abstraction::XmlFileWriterRegistry::registerXmlFileWriter < int > ( ); + abstraction::XmlFileWriterRegistry::registerXmlFileWriter < double > ( ); + abstraction::XmlFileWriterRegistry::registerXmlFileWriter < std::string > ( ); + + abstraction::ValuePrinterRegistry::registerValuePrinter < int > ( ); + abstraction::ValuePrinterRegistry::registerValuePrinter < double > ( ); + abstraction::ValuePrinterRegistry::registerValuePrinter < std::string > ( ); + + abstraction::ImmediateRegistry::registerImmediate < int > ( ); + abstraction::ImmediateRegistry::registerImmediate < std::string > ( ); + } +}; + +auto primitiveCasts = PrimitiveCasts ( ); + +} /* namespace abstraction */ diff --git a/alib2common/src/abstraction/Registry.cpp b/alib2common/src/abstraction/Registry.cpp new file mode 100644 index 0000000000..25cd777c4c --- /dev/null +++ b/alib2common/src/abstraction/Registry.cpp @@ -0,0 +1,57 @@ +/* + * Registry.cpp + * + * Created on: 10. 7. 2017 + * Author: Jan Travnicek + */ + +#include <abstraction/Registry.h> + +#include <abstraction/AlgorithmRegistry.hpp> +#include <abstraction/ImmediateRegistry.hpp> +#include <abstraction/XmlParserRegistry.hpp> +#include <abstraction/XmlFileWriterRegistry.hpp> +#include <abstraction/ValuePrinterRegistry.hpp> +#include <abstraction/CastRegistry.hpp> +#include <abstraction/NormalizeRegistry.hpp> +#include <abstraction/DowncastRegistry.hpp> + +namespace abstraction { + +std::shared_ptr < abstraction::OperationAbstraction > Registry::getAlgorithmAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes ) { + return AlgorithmRegistry::getAbstraction ( std::move ( name ), paramTypes ); +} + +std::shared_ptr < abstraction::OperationAbstraction > Registry::getAlgorithmAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes, bool & unwrap, bool & normalize ) { + return AlgorithmRegistry::getAbstraction ( std::move ( name ), paramTypes, unwrap, normalize ); +} + +std::shared_ptr < abstraction::OperationAbstraction > Registry::getCastAbstraction ( std::string target, std::string param ) { + return CastRegistry::getAbstraction ( std::move ( target ), std::move ( param ) ); +} + +std::shared_ptr < abstraction::OperationAbstraction > Registry::getImmediateAbstraction ( std::string result, std::string value ) { + return ImmediateRegistry::getAbstraction ( std::move ( result ), std::move ( value ) ); +} + +std::shared_ptr < abstraction::OperationAbstraction > Registry::getNormalizeAbstraction ( std::string param ) { + return NormalizeRegistry::getAbstraction ( std::move ( param ) ); +} + +std::shared_ptr < abstraction::OperationAbstraction > Registry::getDowncastAbstraction ( std::string concrete, std::string base ) { + return DowncastRegistry::getAbstraction ( std::move ( concrete ), std::move ( base ) ); +} + +std::shared_ptr < abstraction::OperationAbstraction > Registry::getValuePrinterAbstraction ( std::string param ) { + return ValuePrinterRegistry::getAbstraction ( std::move ( param ) ); +} + +std::shared_ptr < abstraction::OperationAbstraction > Registry::getXmlFileWriterAbstraction ( std::string param, std::string filename ) { + return XmlFileWriterRegistry::getAbstraction ( std::move ( param ), std::move ( filename ) ); +} + +std::shared_ptr < abstraction::OperationAbstraction > Registry::getXmlParserAbstraction ( std::string typeName, std::deque < sax::Token > tokens ) { + return XmlParserRegistry::getAbstraction ( std::move ( typeName ), std::move ( tokens ) ); +} + +} /* namespace abstraction */ diff --git a/alib2common/src/abstraction/Registry.h b/alib2common/src/abstraction/Registry.h new file mode 100644 index 0000000000..e61f1d5075 --- /dev/null +++ b/alib2common/src/abstraction/Registry.h @@ -0,0 +1,31 @@ +/* + * Registry.h + * + * Created on: 10. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _REGISTRY_H_ +#define _REGISTRY_H_ + +#include <abstraction/OperationAbstraction.hpp> + +namespace abstraction { + +class Registry { +public: + static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes ); + static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes, bool & unwrap, bool & normalize ); + static std::shared_ptr < abstraction::OperationAbstraction > getCastAbstraction ( std::string target, std::string param ); + static std::shared_ptr < abstraction::OperationAbstraction > getImmediateAbstraction ( std::string result, std::string value ); + static std::shared_ptr < abstraction::OperationAbstraction > getNormalizeAbstraction ( std::string param ); + static std::shared_ptr < abstraction::OperationAbstraction > getDowncastAbstraction ( std::string concrete, std::string base ); + static std::shared_ptr < abstraction::OperationAbstraction > getValuePrinterAbstraction ( std::string param ); + static std::shared_ptr < abstraction::OperationAbstraction > getXmlFileWriterAbstraction ( std::string param, std::string filename ); + static std::shared_ptr < abstraction::OperationAbstraction > getXmlParserAbstraction ( std::string typeName, std::deque < sax::Token > tokens ); +}; + +} /* namespace abstraction */ + +#endif /* _REGISTRY_H_ */ + diff --git a/alib2common/src/abstraction/ResultClassSelector.hpp b/alib2common/src/abstraction/ResultClassSelector.hpp new file mode 100644 index 0000000000..b7a2813252 --- /dev/null +++ b/alib2common/src/abstraction/ResultClassSelector.hpp @@ -0,0 +1,29 @@ +/* + * ResultClassSelector.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _RESULT_CLASS_SELECTOR_H_ +#define _RESULT_CLASS_SELECTOR_H_ + +#include <abstraction/VoidOperationAbstraction.hpp> +#include <abstraction/ValueOperationAbstraction.hpp> +#include <tuple> + +namespace abstraction { + +template < class ReturnType > +struct ResultClassSelector { + typedef ValueOperationAbstraction < ReturnType > OutputClass; +}; + +template < > +struct ResultClassSelector < void > { + typedef VoidOperationAbstraction OutputClass; +}; + +} /* namespace abstraction */ + +#endif /* _RESULT_CLASS_SELECTOR_H_ */ diff --git a/alib2common/src/abstraction/UnaryOperationAbstraction.hpp b/alib2common/src/abstraction/UnaryOperationAbstraction.hpp new file mode 100644 index 0000000000..6b443e2087 --- /dev/null +++ b/alib2common/src/abstraction/UnaryOperationAbstraction.hpp @@ -0,0 +1,91 @@ +/* + * UnaryOperationAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _UNARY_OPERATION_ABSTRACTION_HPP_ +#define _UNARY_OPERATION_ABSTRACTION_HPP_ + +#include <abstraction/ResultClassSelector.hpp> +#include <tuple> +#include <abstraction/Registry.h> + +namespace abstraction { + +template < class ReturnType, class ParamType > +class UnaryOperationAbstraction : public ResultClassSelector < ReturnType >::OutputClass { +protected: + std::shared_ptr < ValueOperationAbstraction < typename std::decay < ParamType >::type > > m_param; + +private: + virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index ) override { + if ( index != 0 ) + throw exception::CommonException ( "Out of range index: " + std::to_string ( index ) + " max: " + std::to_string ( numberOfParams ( ) ) + "." ); + + std::shared_ptr < ValueOperationAbstraction < ParamType > > validData = std::dynamic_pointer_cast < ValueOperationAbstraction < ParamType > > ( input ); + if ( validData ) { + m_param = validData; + return true; + } else { + return false; + } + } + + virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & input ) override { + if ( m_param != input ) + return false; + + m_param = nullptr; + return true; + } + +public: + UnaryOperationAbstraction ( ) { + } + + virtual bool inputsReady ( ) const override { + return m_param && m_param->isReady ( ); + } + + virtual bool inputsAttached ( ) const override { + return ( bool ) m_param; + } + + virtual bool eval ( ) override { + if ( ! inputsAttached ( ) ) + return false; + + if ( this->cached ( ) ) + return true; + + this->m_param->eval ( ); + + return this->run ( ); + } + + virtual unsigned numberOfParams ( ) const override { + return 1; + } + + virtual std::shared_ptr < OperationAbstraction > getImmediateValueFromParam ( unsigned index, const std::string & value ) const override { + if ( index != 0 ) + throw std::out_of_range ( "Invalid input index" ); + + std::string paramType = std::type_name < ParamType > ( ); + return Registry::getImmediateAbstraction ( std::move ( paramType ), value ); + } + + virtual std::shared_ptr < OperationAbstraction > getXmlParserFromParam ( unsigned index, std::deque < sax::Token > tokens ) const override { + if ( index != 0 ) + throw exception::CommonException ( "Out of range index: " + std::to_string ( index ) + " max: " + std::to_string ( numberOfParams ( ) ) + "." ); + + std::string paramType = std::type_name < ParamType > ( ); + return Registry::getXmlParserAbstraction ( std::move ( paramType ), std::move ( tokens ) ); + } +}; + +} /* namespace abstraction */ + +#endif /* _UNARY_OPERATION_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/ValueOperationAbstraction.hpp b/alib2common/src/abstraction/ValueOperationAbstraction.hpp new file mode 100644 index 0000000000..85f5aa9c6a --- /dev/null +++ b/alib2common/src/abstraction/ValueOperationAbstraction.hpp @@ -0,0 +1,91 @@ +/* + * ValueOperationAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _VALUE_OPERATION_ABSTRACTION_HPP_ +#define _VALUE_OPERATION_ABSTRACTION_HPP_ + +#include <abstraction/OperationAbstraction.hpp> +#include <tuple> +#include <memory> +#include <typeindex> +#include <abstraction/Registry.h> + +namespace abstraction { + +template < class ReturnType > +class ValueOperationAbstraction : public OperationAbstraction { +protected: + std::unique_ptr < ReturnType > m_data; + +public: + typedef ReturnType return_type; + + template < typename Callable, typename ... Ts, size_t ... Indexes > + inline void run_helper ( Callable callback, const std::tuple < Ts ... > & inputs, std::index_sequence < Indexes ... > ) { + if ( m_data == nullptr ) + m_data = std::unique_ptr < ReturnType > ( callback ( std::get < Indexes > ( inputs )->getData ( ) ... ) ); + } + + template < typename Callable, typename T > + inline void run_helper ( Callable callback, const T & input ) const { + if ( m_data == nullptr ) + m_data = std::unique_ptr < ReturnType > ( callback ( input->getData ( ) ) ); + } + + bool isReady ( ) const { + return m_data != nullptr; + } + + ReturnType & getData ( ) const { + return * m_data; + } + + virtual std::shared_ptr < OperationAbstraction > getXmlFileWriterFromResult ( const std::string & filename ) const override { + std::string param = std::type_name < ReturnType > ( ); + return Registry::getXmlFileWriterAbstraction ( param, filename ); + } + + virtual std::shared_ptr < OperationAbstraction > getValuePrinterFromResult ( ) const override { + std::string param = std::type_name < ReturnType > ( ); + return Registry::getValuePrinterAbstraction ( param ); +} + + virtual std::shared_ptr < OperationAbstraction > getCastFromResult ( const std::string & target ) const override { + std::string param = std::type_name < ReturnType > ( ); + return Registry::getCastAbstraction ( target, param ); + } + + virtual std::shared_ptr < OperationAbstraction > getNormalizeResult ( ) const override { + std::string param = std::type_name < ReturnType > ( ); + return Registry::getNormalizeAbstraction ( param ); + } + + virtual std::shared_ptr < OperationAbstraction > getDowncastResult ( ) const override { + std::string base = std::type_name < ReturnType > ( ); + std::string concrete = std::type_name ( runtime_type ( ) ); + return Registry::getDowncastAbstraction ( concrete, base ); + } + + virtual std::type_index type ( ) const override { + return std::type_index ( typeid ( ReturnType ) ); + } + + virtual std::type_index runtime_type ( ) const override { + if ( isReady ( ) ) + return std::type_index ( typeid ( getData ( ) ) ); + else + throw exception::CommonException ( "Runtime type unknown before evaluation." ); + } + + virtual bool cached ( ) const override { + return isReady ( ); + } +}; + +} /* namespace abstraction */ + +#endif /* _VALUE_OPERATION_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/ValuePrinterAbstraction.hpp b/alib2common/src/abstraction/ValuePrinterAbstraction.hpp new file mode 100644 index 0000000000..ed87b2412e --- /dev/null +++ b/alib2common/src/abstraction/ValuePrinterAbstraction.hpp @@ -0,0 +1,33 @@ +/* + * ValuePrinterAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _VALUE_PRINTER_ABSTRACTION_HPP_ +#define _VALUE_PRINTER_ABSTRACTION_HPP_ + +#include <abstraction/UnaryOperationAbstraction.hpp> +#include <tuple> + +namespace abstraction { + +template < class ParamType > +class ValuePrinterAbstraction : public UnaryOperationAbstraction < void, ParamType > { +public: + ValuePrinterAbstraction ( ) { + } + + virtual bool run ( ) override { + if ( ! this->inputsReady ( ) ) + return false; + + std::cout << this->m_param->getData ( ); + return true; + } +}; + +} /* namespace abstraction */ + +#endif /* _VALUE_PRINTER_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/ValuePrinterRegistry.hpp b/alib2common/src/abstraction/ValuePrinterRegistry.hpp new file mode 100644 index 0000000000..e18ceb73ec --- /dev/null +++ b/alib2common/src/abstraction/ValuePrinterRegistry.hpp @@ -0,0 +1,74 @@ +/* + * ValuePrinterRegistry.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _VALUE_PRINTER_REGISTRY_HPP_ +#define _VALUE_PRINTER_REGISTRY_HPP_ + +#include <memory> +#include <string> + +#include <exception/CommonException.h> +#include <abstraction/OperationAbstraction.hpp> + +namespace abstraction { + +class ValuePrinterRegistry { + class Entry { + public: + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0; + + }; + + template < class Param > + class EntryImpl : public Entry { + public: + EntryImpl ( ) { + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override; + }; + + static std::map < std::string, std::unique_ptr < Entry > > & getEntries ( ) { + static std::map < std::string, std::unique_ptr < Entry > > fileWriters; + return fileWriters; + } + +public: + template < class ParamType > + static void registerValuePrinter ( std::string param ) { + getEntries ( ).insert ( std::make_pair ( param, std::unique_ptr < Entry > ( new EntryImpl < ParamType > ( ) ) ) ); + } + + template < class ParamType > + static void registerValuePrinter ( ) { + std::string param = std::type_name < ParamType > ( ); + registerValuePrinter < ParamType > ( std::move ( param ) ); + } + + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string param ) { + auto res = getEntries ( ).find ( param ); + if ( res == getEntries ( ).end ( ) ) + throw exception::CommonException ( "Entry " + param + " not available." ); + + return res->second->getAbstraction ( ); + } +}; + +} /* namespace abstraction */ + +#include <abstraction/ValuePrinterAbstraction.hpp> + +namespace abstraction { + +template < class Param > +std::shared_ptr < abstraction::OperationAbstraction > ValuePrinterRegistry::EntryImpl < Param >::getAbstraction ( ) const { + return std::make_shared < abstraction::ValuePrinterAbstraction < Param > > ( ); +} + +} /* namespace abstraction */ + +#endif /* _VALUE_PRINTER_REGISTRY_HPP_ */ diff --git a/alib2common/src/abstraction/VoidOperationAbstraction.hpp b/alib2common/src/abstraction/VoidOperationAbstraction.hpp new file mode 100644 index 0000000000..2b479f01a2 --- /dev/null +++ b/alib2common/src/abstraction/VoidOperationAbstraction.hpp @@ -0,0 +1,63 @@ +/* + * VoidOperationAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _VOID_OPERATION_ABSTRACTION_HPP_ +#define _VOID_OPERATION_ABSTRACTION_HPP_ + +#include <abstraction/OperationAbstraction.hpp> +#include <tuple> + +namespace abstraction { + +class VoidOperationAbstraction : public OperationAbstraction { +public: + template < typename Callable, typename ... Ts, size_t ... Indexes > + inline void run_helper ( Callable callback, const std::tuple < Ts ... > & inputs, std::index_sequence < Indexes ... > ) const { + callback ( std::get < Indexes > ( inputs )->getData ( ) ... ); + } + + template < typename Callable, typename T > + inline void run_helper ( Callable callback, const T & input ) const { + callback ( input->getData ( ) ); + } + + virtual std::shared_ptr < OperationAbstraction > getXmlFileWriterFromResult ( const std::string & ) const override { + throw exception::CommonException ( "Void algorithm does not have a result." ); + } + + virtual std::shared_ptr < OperationAbstraction > getValuePrinterFromResult ( ) const override { + throw exception::CommonException ( "Void algorithm does not have a result." ); + } + + virtual std::shared_ptr < OperationAbstraction > getCastFromResult ( const std::string & ) const override { + throw exception::CommonException ( "Void algorithm does not have a result." ); + } + + virtual std::shared_ptr < OperationAbstraction > getNormalizeResult ( ) const override { + throw exception::CommonException ( "Void algorithm does not have a result." ); + } + + virtual std::shared_ptr < OperationAbstraction > getDowncastResult ( ) const override { + throw exception::CommonException ( "Void algorithm does not have a result." ); + } + + virtual std::type_index type ( ) const override { + return std::type_index ( typeid ( void ) ); + } + + virtual std::type_index runtime_type ( ) const override { + return std::type_index ( typeid ( void ) ); + } + + virtual bool cached ( ) const override { + return false; + } +}; + +} /* namespace abstraction */ + +#endif /* _VOID_OPERATION_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/XmlFileWriterAbstraction.hpp b/alib2common/src/abstraction/XmlFileWriterAbstraction.hpp new file mode 100644 index 0000000000..9fb60ef3ec --- /dev/null +++ b/alib2common/src/abstraction/XmlFileWriterAbstraction.hpp @@ -0,0 +1,35 @@ +/* + * XmlFileWriterAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _XML_FILE_WRITER_ABSTRACTION_HPP_ +#define _XML_FILE_WRITER_ABSTRACTION_HPP_ + +#include <abstraction/UnaryOperationAbstraction.hpp> +#include <tuple> + +namespace abstraction { + +template < class ParamType > +class XmlFileWriterAbstraction : public UnaryOperationAbstraction < void, ParamType > { + std::string m_filename; + +public: + XmlFileWriterAbstraction ( std::string filename ) : m_filename ( filename ) { + } + + virtual bool run ( ) override { + if ( ! this->inputsReady ( ) ) + return false; + + alib::XmlDataFactory::toFile ( this->m_param->getData ( ), m_filename ); + return true; + } +}; + +} /* namespace abstraction */ + +#endif /* _XML_FILE_WRITER_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/XmlFileWriterRegistry.hpp b/alib2common/src/abstraction/XmlFileWriterRegistry.hpp new file mode 100644 index 0000000000..26ab05b9a5 --- /dev/null +++ b/alib2common/src/abstraction/XmlFileWriterRegistry.hpp @@ -0,0 +1,75 @@ +/* + * XmlFileWriterRegistry.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _XML_FILE_WRITER_REGISTRY_HPP_ +#define _XML_FILE_WRITER_REGISTRY_HPP_ + +#include <memory> +#include <string> + +#include <exception/CommonException.h> +#include <abstraction/OperationAbstraction.hpp> + +namespace abstraction { + +class XmlFileWriterRegistry { + class Entry { + public: + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string filename ) const = 0; + + }; + + template < class Param > + class EntryImpl : public Entry { + public: + EntryImpl ( ) { + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string filename ) const override; + }; + + static std::map < std::string, std::unique_ptr < Entry > > & getEntries ( ) { + static std::map < std::string, std::unique_ptr < Entry > > fileWriters; + return fileWriters; + } + +public: + template < class ParamType > + static void registerXmlFileWriter ( std::string param ) { + getEntries ( ).insert ( std::make_pair ( param, std::unique_ptr < Entry > ( new EntryImpl < ParamType > ( ) ) ) ); + } + + template < class ParamType > + static void registerXmlFileWriter ( ) { + std::string param = std::type_name < ParamType > ( ); + registerXmlFileWriter < ParamType > ( std::move ( param ) ); + } + + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string param, std::string filename ) { + auto res = getEntries ( ).find ( param ); + if ( res == getEntries ( ).end ( ) ) + throw exception::CommonException ( "Entry " + param + " not available." ); + + return res->second->getAbstraction ( std::move ( filename ) ); + } +}; + +} /* namespace abstraction */ + +#include <abstraction/XmlFileWriterAbstraction.hpp> + +namespace abstraction { + +template < class Param > +std::shared_ptr < abstraction::OperationAbstraction > XmlFileWriterRegistry::EntryImpl < Param >::getAbstraction ( std::string filename ) const { + return std::make_shared < abstraction::XmlFileWriterAbstraction < Param > > ( std::move ( filename ) ); +} + + +} /* namespace abstraction */ + +#endif /* _XML_FILE_WRITER_REGISTRY_HPP_ */ diff --git a/alib2common/src/abstraction/XmlParserAbstraction.hpp b/alib2common/src/abstraction/XmlParserAbstraction.hpp new file mode 100644 index 0000000000..a0191f2e1b --- /dev/null +++ b/alib2common/src/abstraction/XmlParserAbstraction.hpp @@ -0,0 +1,36 @@ +/* + * XmlParserAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _XML_PARSER_ABSTRACTION_HPP_ +#define _XML_PARSER_ABSTRACTION_HPP_ + +#include <abstraction/NullaryOperationAbstraction.hpp> +#include <tuple> + +namespace abstraction { + +template < class ReturnType > +class XmlParserAbstraction : public NullaryOperationAbstraction < ReturnType > { + std::deque < sax::Token > m_tokens; + +public: + XmlParserAbstraction ( std::deque < sax::Token > tokens ) : m_tokens ( std::move ( tokens ) ) { + } + + virtual bool run ( ) override { + if ( this->m_data != nullptr ) + return true; + + ReturnType res = alib::XmlDataFactory::fromTokens ( std::move ( m_tokens ) ); + this->m_data = std::unique_ptr < ReturnType > ( static_cast < ReturnType * > ( std::move ( res ).plunder ( ) ) ); + return true; + } +}; + +} /* namespace abstraction */ + +#endif /* _XML_PARSER_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/XmlParserRegistry.hpp b/alib2common/src/abstraction/XmlParserRegistry.hpp new file mode 100644 index 0000000000..d71bda9166 --- /dev/null +++ b/alib2common/src/abstraction/XmlParserRegistry.hpp @@ -0,0 +1,70 @@ +/* + * XmlParserRegistry.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _XML_PARSER_REGISTRY_HPP_ +#define _XML_PARSER_REGISTRY_HPP_ + +#include <memory> +#include <string> + +#include <exception/CommonException.h> +#include <abstraction/OperationAbstraction.hpp> + +namespace abstraction { + +class XmlParserRegistry { + class Entry { + public: + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::deque < sax::Token > data ) const = 0; + + }; + + template < class Return > + class EntryImpl : public Entry { + public: + EntryImpl ( ) { + } + + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::deque < sax::Token > data ) const override; + }; + + static std::map < std::string, std::unique_ptr < Entry > > & getEntries ( ) { + static std::map < std::string, std::unique_ptr < Entry > > parsers; + return parsers; + } + +public: + template < class ReturnType > + static void registerXmlParser ( ) { + std::string ret = alib::xmlApi < ReturnType >::xmlTagName ( ); + + getEntries ( ).insert ( std::make_pair ( ret, std::unique_ptr < Entry > ( new EntryImpl < ReturnType > ( ) ) ) ); + } + + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string typeName, std::deque < sax::Token > tokens ) { + auto type = getEntries ( ).find ( typeName ); + if ( type == getEntries ( ).end ( ) ) + throw exception::CommonException ( "Entry " + typeName + " not available." ); + + return type->second->getAbstraction ( std::move ( tokens ) ); + } +}; + +} /* namespace abstraction */ + +#include <abstraction/XmlParserAbstraction.hpp> + +namespace abstraction { + +template < class Return > +std::shared_ptr < abstraction::OperationAbstraction > XmlParserRegistry::EntryImpl < Return >::getAbstraction ( std::deque < sax::Token > data ) const { + return std::make_shared < abstraction::XmlParserAbstraction < Return > > ( std::move ( data ) ); +} + +} /* namespace abstraction */ + +#endif /* _XML_PARSER_REGISTRY_HPP_ */ -- GitLab