Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ValueProvider.hpp 2.90 KiB
/*
 * ValueProvider.hpp
 *
 *  Created on: 11. 7. 2017
 *	  Author: Jan Travnicek
 */

#ifndef _VALUE_PROVIDER_HPP_
#define _VALUE_PROVIDER_HPP_

#include <exception>

#include <alib/utility>

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:
	Type getValue ( bool move ) const {
		if constexpr ( std::is_copy_constructible_v < Type > && std::is_move_constructible_v < Type > ) {
			if ( ! isConst ( ) && move )
				return std::move ( getData ( ) );
			else
				return getData ( );
		} else if constexpr ( std::is_copy_constructible_v < Type > && ! std::is_move_constructible_v < Type > ) {
			if ( ! isConst ( ) && move )
				throw std::domain_error ( "Value not move constructible" );
			else
				return getData ( );
		} else if constexpr ( ! std::is_copy_constructible_v < Type > && std::is_move_constructible_v < Type > ) {
			if ( ! isConst ( ) && move )
				return std::move ( getData ( ) );
			else
				throw std::domain_error ( "Value not copy constructible" );
		} else { // ! std::is_copy_constructible_v < Type > && ! std::is_move_constructible_v < Type >
			if ( ! isConst ( ) && move )
				throw std::domain_error ( "Value not move constructible" );
			else
				throw std::domain_error ( "Value not copy constructible" );
		}
	}
};

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:
	Type & getValue ( bool ) const {
		return getData ( );
	}
};

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:
	const Type & getValue ( bool ) const {
		return getConstData ( );
	}
};

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:
	Type && getValue ( bool move ) const {
		if ( move )
			return std::move ( getData ( ) );
		else
			throw std::domain_error ( "Value not copy constructible" );
	}
};

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:
	const Type && getValue ( bool move ) const {
		if ( move )
			return std::move ( getConstData ( ) );
		else
			throw std::domain_error ( "Value not copy constructible" );
	}
};

} /* namespace abstraction */

#endif /* _VALUE_PROVIDER_HPP_ */