/* * StatusLogic.hpp * * Created on: 29 сент. 2019 г. * Author: user */ #ifndef SOURCE_SCHEMATIC_STATUSLOGIC_HPP_ #define SOURCE_SCHEMATIC_STATUSLOGIC_HPP_ #include "../systemic/IStatus.hh" #include namespace systemic { namespace detail { class StatusNot : public IStatus { IStatus & status; public: StatusNot(IStatus & status) : status(status) {} virtual operator bool() const { return not status; } virtual ~StatusNot() = default; }; template class StatusAnd : public IStatus { public: template StatusAnd( IStatus* (&pStatusArray)[M] ) : n(M > N ? N : M) { for(int i = 0; i < n; i++) pStatuses[i] = pStatusArray[i]; } StatusAnd( IStatus * pStatusArray[], int array_size ) : n(array_size > N ? N : array_size) { for(int i = 0; i < n; i++) pStatuses[i] = pStatusArray[i]; } #if __cplusplus >= 201103L StatusAnd(std::initializer_list statusList) : n(statusList.size()) { int i = 0; for(auto & status : statusList) { pStatuses[i++] = status; } } #endif virtual operator bool() const { bool result = true; for(int i = 0; i < n; i++) { result = result && (bool)(*pStatuses[i]); } return result; } virtual ~StatusAnd() = default; private: IStatus * pStatuses[N]; const int n; }; template class StatusNAnd : public StatusNot { private: StatusAnd statuses; public: template StatusNAnd( IStatus* (&pStatusArray)[M] ) : statuses(pStatusArray), StatusNot(statuses) {} StatusNAnd( IStatus * pStatusArray[], int array_size ) : statuses(pStatusArray, array_size), StatusNot(statuses) {} virtual ~StatusNAnd() = default; }; template class StatusOr : public IStatus { public: template StatusOr( IStatus* (&pStatusArray)[M] ) : n(M > N ? N : M) { for(int i = 0; i < n; i++) pStatuses[i] = pStatusArray[i]; } StatusOr( IStatus * pStatusArray[], int array_size ) : n(array_size > N ? N : array_size) { for(int i = 0; i < n; i++) pStatuses[i] = pStatusArray[i]; } #if __cplusplus >= 201103L StatusOr(std::initializer_list statusList) : n(statusList.size()) { int i = 0; for(auto & status : statusList) { pStatuses[i++] = status; } } #endif virtual operator bool() const { bool result = false; for(int i = 0; i < n; i++) { result = result || (bool)(*pStatuses[i]); } return result; } virtual ~StatusOr() = default; private: IStatus * pStatuses[N]; const int n; }; template class StatusNOr : public StatusNot { private: StatusOr statuses; public: template StatusNOr(IStatus * (&pStatusArray)[M]) : statuses(pStatusArray), StatusNot(statuses) {} StatusNOr( IStatus * pStatusArray[], int array_size ) : statuses(pStatusArray, array_size), StatusNot(statuses) {} virtual ~StatusNOr() = default; }; //возможна индивидуальная инверсия по каждому входу template class StatusVarAnd : public IStatus { public: template StatusVarAnd( std::pair (&m)[M] ) : n(M > N ? N : M) { for(int i = 0; i < n; i++) { pStatuses[i] = m[i].first; invert[i] = m[i].second; } } StatusVarAnd( std::pair m[], int array_size ) : n(array_size > N ? N : array_size) { for(int i = 0; i < n; i++) { pStatuses[i] = m[i].first; invert[i] = m[i].second; } } virtual operator bool() const { bool result = true; for(int i = 0; i < n; i++) { result = result && ( invert[i] != ( *pStatuses[i] ) ); } return result; } virtual ~StatusVarAnd() = default; private: IStatus * pStatuses[N]; bool invert[N]; const int n; }; }} #endif /* SOURCE_SCHEMATIC_STATUSLOGIC_HPP_ */