/*
 * vector.hpp
 *
 * This file is part of Algorithms library toolkit.
 * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz)

 * Algorithms library toolkit is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * Algorithms library toolkit is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with Algorithms library toolkit.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Created on: Feb 28, 2014
 * Author: Jan Travnicek
 */

#pragma once

#include <vector>
#include <ostream>
#include <sstream>
#include <string>
#include <iostream>

#include <extensions/range.hpp>

namespace ext {

/**
 * \brief
 * Class extending the vector class from the standard library. Original reason is to allow printing of the container with overloaded operator <<.
 *
 * The class mimics the behavior of the vector from the standatd library.
 *
 * \tparam T the type of values inside the vector
 * \tparam Alloc the allocator of values of type T
 */
template < class T, class Alloc = std::allocator < T > >
class vector : public std::vector < T, Alloc > {
public:
	/**
	 * Inherit constructors of the standard vector
	 */
	using std::vector< T, Alloc >::vector; // NOLINT(modernize-use-equals-default)

	/**
	 * Inherit operator = of the standard vector
	 */
	using std::vector< T, Alloc >::operator =;

	/**
	 * \brief
	 * The type of values iterator.
	 */
	using iterator = typename std::vector < T, Alloc >::iterator;

	/**
	 * \brief
	 * The type of constant values iterator.
	 */
	using const_iterator = typename std::vector < T, Alloc >::const_iterator;

	/**
	 * \brief
	 * The type of reverse values iterator.
	 */
	using reverse_iterator = typename std::vector < T, Alloc >::reverse_iterator;

	/**
	 * \brief
	 * The type of constant reverse values iterator.
	 */
	using const_reverse_iterator = typename std::vector < T, Alloc >::const_reverse_iterator;

#ifndef __clang__

	/**
	 * Default constructor needed by g++ since it is not inherited
	 */
	vector ( ) = default;

	/**
	 * Copy constructor needed by g++ since it is not inherited
	 */
	vector ( const vector & other ) = default;

	/**
	 * Move constructor needed by g++ since it is not inherited
	 */
	vector ( vector && other ) = default;

	/**
	 * Copy operator = needed by g++ since it is not inherited
	 */
	vector & operator = ( vector && other ) = default;

	/**
	 * Move operator = needed by g++ since it is not inherited
	 */
	vector & operator = ( const vector & other ) = default;
#endif
	/**
	 * Constructor from range of values.
	 *
	 * \tparam Iterator the type of range iterator
	 *
	 * \param range the source range
	 */
	template < class Iterator >
	explicit vector ( const ext::iterator_range < Iterator > & range ) : vector ( range.begin ( ), range.end ( ) ) {
	}

	/**
	 * \brief
	 * Inherited behavior of begin for non-const instance.
	 *
	 * \return iterator the first element of vector
	 */
	auto begin ( ) & {
		return std::vector < T, Alloc >::begin ( );
	}

	/**
	 * \brief
	 * Inherited behavior of begin for const instance.
	 *
	 * \return const_iterator the first element of vector
	 */
	auto begin ( ) const & {
		return std::vector < T, Alloc >::begin ( );
	}

	/**
	 * \brief
	 * Inherited behavior of begin for rvalues.
	 *
	 * \return move_iterator the first element of vector
	 */
	auto begin ( ) && {
		return make_move_iterator ( this->begin ( ) );
	}

	/**
	 * \brief
	 * Inherited behavior of end for non-const instance.
	 *
	 * \return iterator to one after the last element of vector
	 */
	auto end ( ) & {
		return std::vector < T, Alloc >::end ( );
	}

	/**
	 * \brief
	 * Inherited behavior of end for const instance.
	 *
	 * \return const_iterator to one after the last element of vector
	 */
	auto end ( ) const & {
		return std::vector < T, Alloc >::end ( );
	}

	/**
	 * \brief
	 * Inherited behavior of end for rvalues.
	 *
	 * \return move_iterator to one after the last element of vector
	 */
	auto end ( ) && {
		return make_move_iterator ( this->end ( ) );
	}

	/**
	 * \brief
	 * Make range of non-const begin to end iterators.
	 *
	 * \return full range over container values
	 */
	auto range ( ) & {
		auto endIter = end ( );
		auto beginIter = begin ( );
		return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter );
	}

	/**
	 * \brief
	 * Make range of non-const begin to end iterators.
	 *
	 * \return full range over container values
	 */
	auto range ( ) const & {
		auto endIter = end ( );
		auto beginIter = begin ( );
		return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter );
	}

	/**
	 * \brief
	 * Make range of move begin to end iterators.
	 *
	 * \return full range over container values
	 */
	auto range ( ) && {
		auto endIter = std::move ( * this ).end ( );
		auto beginIter = std::move ( * this ).begin ( );
		return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter );
	}

	/**
	 * Get original insert on the top level.
	 */
	using std::vector < T, Alloc >::insert;

	/**
	 * \brief
	 * Inserts the value on position given by iterator \p pos
	 *
	 * \param pos the position to insert at
	 * \param value the value to insert
	 *
	 * \return updated iterator to the newly inserted value
	 */
	reverse_iterator insert ( const_reverse_iterator pos, const T & value ) {
		return reverse_iterator ( std::next ( insert ( pos.base ( ), value ) ) );
	}

	/**
	 * \brief
	 * Inserts the value on position given by iterator \p pos
	 *
	 * \param pos the position to insert at
	 * \param value the value to insert
	 *
	 * \return updated iterator to the newly inserted value
	 */
	reverse_iterator insert ( const_reverse_iterator pos, T && value ) {
		return reverse_iterator ( std::next ( insert ( pos.base ( ), std::move ( value ) ) ) );
	}

	/**
	 * \brief
	 * Inserts the \p count copies of value on position given by iterator \p pos
	 *
	 * \param pos the position to insert at
	 * \param count the number of copies to insert
	 * \param value the value to insert
	 *
	 * \return updated iterator to the newly inserted value
	 */
	reverse_iterator insert ( const_reverse_iterator pos, size_t count, const T & value ) {
		return reverse_iterator ( std::next ( insert ( pos.base ( ), count, value ) ) );
	}

	/**
	 * \brief
	 * Inserts the values from the given range to positions starting at given iterator \p pos
	 *
	 * \tparam InputIt the iterator type
	 *
	 * \param first the begining of the range
	 * \param last the end of the range
	 *
	 * \return updated iterator to the newly inserted value
	 */
	template < class InputIt >
	reverse_iterator insert ( const_reverse_iterator pos, InputIt first, InputIt last ) {
		return reverse_iterator ( std::next ( insert ( pos.base ( ), first, last ) ) );
	}

	/**
	 * \brief
	 * Inserts the values from the given initializer list to positions starting at given iterator \p pos
	 *
	 * \param pos the position to insert at
	 * \param ilist the initializer list
	 *
	 * \return updated iterator to the newly inserted value
	 */
	reverse_iterator insert ( const_reverse_iterator pos, std::initializer_list < T > ilist ) {
		return reverse_iterator ( std::next ( insert ( pos.base ( ), std::move ( ilist ) ) ) );
	}

	/**
	 * Get original emplace on the top level.
	 */
	using std::vector < T, Alloc >::emplace;

	/**
	 * \brief
	 * Inserts a new value to the container at position given by parameter \p pos. The new value is constructed inside the method from constructor parameters.
	 *
	 * \tparam Args ... the types of arguments of the T constructor
	 *
	 * \param pos the position to set
	 * \param args ... the arguments of the T constructor
	 *
	 * \return updated iterator to the newly inserted value
	 */
	template < class ... Args >
	reverse_iterator emplace ( const_reverse_iterator pos, Args && ... args ) {
		return reverse_iterator ( std::next ( emplace ( pos.base ( ), std::forward < Args > ( args ) ... ) ) );
	}

	/**
	 * Get original emplace on the top level.
	 */
	using std::vector < T, Alloc >::erase;

	/**
	 * \brief
	 * Removes element from the container at position given by parameter \p pos
	 *
	 * \param pos the iterator pointing to the value to removed
	 *
	 * \returns updated iterator to value after the removed one
	 */
	iterator erase ( iterator pos ) {
		return erase ( const_iterator ( pos ) );
	}

	/**
	 * \brief
	 * Removes element from the container at position given by parameter \p pos
	 *
	 * \param pos the iterator pointing to the value to removed
	 *
	 * \returns updated iterator to value after the removed one
	 */
	reverse_iterator erase ( reverse_iterator pos ) {
		return erase ( const_reverse_iterator ( pos ) );
	}

	/**
	 * \brief
	 * Removes element from the container at position given by parameter \p pos
	 *
	 * \param pos the iterator pointing to the value to removed
	 *
	 * \returns updated iterator to value after the removed one
	 */
	reverse_iterator erase ( const_reverse_iterator pos ) {
		return reverse_iterator ( erase ( std::next ( pos ).base ( ) ) );
	}

	/**
	 * \brief
	 * Removes elements from the container in range given parameters \p first and \p last
	 *
	 * \param first the begining of the removed range
	 * \param last the end of the removed range
	 *
	 * \returns updated iterator to value after the removed ones
	 */
	iterator erase ( iterator first, iterator last ) {
		return erase ( const_iterator ( first ), const_iterator ( last ) );
	}

	/**
	 * \brief
	 * Removes elements from the container in range given parameters \p first and \p last
	 *
	 * \param first the begining of the removed range
	 * \param last the end of the removed range
	 *
	 * \returns updated iterator to value after the removed ones
	 */
	reverse_iterator erase ( reverse_iterator first, reverse_iterator last ) {
		return erase ( const_reverse_iterator ( first ), const_reverse_iterator ( last ) );
	}

	/**
	 * \brief
	 * Removes elements from the container in range given parameters \p first and \p last
	 *
	 * \param first the begining of the removed range
	 * \param last the end of the removed range
	 *
	 * \returns updated iterator to value after the removed ones
	 */
	reverse_iterator erase ( const_reverse_iterator first, const_reverse_iterator last ) {
		return reverse_iterator ( erase ( std::next ( first ).base ( ), std::next ( last ).base ( ) ) );
	}

};

/**
 * \brief
 * Operator to print the vector to the output stream.
 *
 * \param out the output stream
 * \param vector the vector to print
 *
 * \tparam T the type of values inside the vector
 * \tparam Ts ... remaining unimportant template parameters of the vector
 *
 * \return the output stream from the \p out
 */
template< class T , class ... Ts >
std::ostream& operator<<(std::ostream& out, const ext::vector<T, Ts ...>& vector) {
	out << "[";

	bool first = true;
	for(const T& item : vector) {
		if(!first) out << ", ";
		first = false;
		out << item;
	}

	out << "]";
	return out;
}

/**
 * \brief
 * Overload of to_string function.
 *
 * \param value the vector to be converted to string
 *
 * \tparam T the type of values inside the vector
 * \tparam Ts ... remaining unimportant template parameters of the vector
 *
 * \return string representation
 */
template < class T, class ... Ts >
std::string to_string ( const ext::vector < T, Ts ... > & value ) {
	std::stringstream ss;
	ss << value;
	return ss.str();
}

/*// the same type as the ext::vector bool's internal storage type
typedef typename std::decay < decltype ( * ( std::declval < ext::vector < bool > > ( ).begin ( )._M_p ) ) >::type vectorBoolInternalType;
// the size of the ext::vector bool's internal storage type
const unsigned vectorBoolInternalTypeInBits = sizeof ( vectorBoolInternalType ) * 8;

// private helper for mask computation
inline vectorBoolInternalType getMask ( size_t dist ) {
	if ( dist == 0 )
		return ~ vectorBoolInternalType { };
	else
		return ( ( vectorBoolInternalType { } + 1 ) << dist ) - 1;
}*/

/**
 * \brief
 * Support for assigning or operator.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the destination instance
 * \param B the source instance
 *
 * \return modified A instance with each bit is result of or operation between respective bits in A and B instances
 */
template < class ... Ts >
ext::vector < bool, Ts ... > & operator |= ( ext::vector < bool, Ts ... > & A, const ext::vector < bool, Ts ... > & B ) {
	// c++ implementation-specific
	/* A.resize ( std::max ( A.size ( ), B.size ( ) ), false );

	typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( );
	typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( );

	while ( itB + 1 < B.end ( ) ) // A is longer or of the same size as B
		* ( itA._M_p ++ ) |= * ( itB._M_p ++ ); // word-at-a-time bitwise operation

	size_t sizeWithin = B.size ( ) % vectorBoolInternalTypeInBits;

	if ( itB < B.end ( ) ) {
		* ( itA._M_p ++ ) |= * ( itB._M_p ++ ) & getMask ( sizeWithin );
	}

	// The rest of A above the size of B can be left intact */

	A.resize ( std::max ( A.size ( ), B.size ( ) ), false );

	typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( );
	typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( );

	for ( ; itB < B.end ( ); ++ itB, ++ itA )
		* itA = * itA | * itB;

	return A;
}

/**
 * \brief
 * Support for or operator.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the first source instance
 * \param B the second source instance
 *
 * \return new vector of booleans with each bit is result of or operation between respective bits in A and B instances
 */
template < class ... Ts >
ext::vector < bool, Ts ... > operator | ( ext::vector < bool, Ts ... > A, const ext::vector < bool, Ts ... > & B ) {
	A |= B;
	return A;
}

/**
 * \brief
 * Support for assigning and operator.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the destination instance
 * \param B the source instance
 *
 * \return modified A instance with each bit is result of and operation between respective bits in A and B instances
 */
template < class ... Ts >
ext::vector < bool, Ts ... > & operator &= ( ext::vector < bool, Ts ... > & A, const ext::vector < bool, Ts ... > & B ) {
	// c++ implementation-specific
	/* A.resize ( std::max ( A.size ( ), B.size ( ) ), false );

	typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( );
	typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( );

	while ( itB + 1 < B.end ( ) ) { // A is longer or of the same size as B
		* ( itA._M_p ++ ) &= * ( itB._M_p ++ ); // word-at-a-time bitwise operation
	}

	size_t sizeWithin = B.size ( ) % vectorBoolInternalTypeInBits;

	if ( itB < B.end ( ) ) {
		* ( itA._M_p ++ ) &= * ( itB._M_p ++ ) & getMask ( sizeWithin );
	}

	while ( itA < A.end ( ) ) { // The rest of A above the size of B shall be zeroed
		* ( itA._M_p ++ ) = 0;
	}*/

	// c++ compilant
	typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( );
	typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( );

	for ( ; itB < B.end ( ) && itA < A.end ( ); ++ itB, ++ itA )
		* itA = * itA & * itB;

	for ( ; itA < A.end ( ); ++ itA )
		* itA = false;

	return A;
}

/**
 * \brief
 * Support for and operator.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the first source instance
 * \param B the second source instance
 *
 * \return new vector of booleans with each bit is result of and operation between respective bits in A and B instances
 */
template < class ... Ts >
ext::vector < bool, Ts ... > operator & ( ext::vector < bool, Ts ... > A, const ext::vector < bool, Ts ... > & B ) {
	A &= B;
	return A;
}

/**
 * \brief
 * Support for assigning xor operator.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the destination instance
 * \param B the source instance
 *
 * \return modified A instance with each bit is result of xor operation between respective bits in A and B instances
 */
template < class ... Ts >
ext::vector < bool, Ts ... > & operator ^= ( ext::vector < bool, Ts ... > & A, const ext::vector < bool, Ts ... > & B ) {
	// c++ implementation-specific
	/* A.resize ( std::max ( A.size ( ), B.size ( ) ), false );

	typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( );
	typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( );

	while ( itB + 1 < B.end ( ) ) // A is longer or of the same size as B
		* ( itA._M_p ++ ) ^= * ( itB._M_p ++ ); // word-at-a-time bitwise operation

	size_t sizeWithin = B.size ( ) % vectorBoolInternalTypeInBits;

	if ( itB < B.end ( ) ) {
		* ( itA._M_p ++ ) ^= * ( itB._M_p ++ ) & getMask ( sizeWithin );
	}

	while ( itA < A.end ( ) ) { // The rest of A above the size of B shall be flipped
		* ( itA._M_p ) = ~ * ( itA._M_p );
		itA._M_p ++;
	}*/

	// c++ compilant
	A.resize ( std::max ( A.size ( ), B.size ( ) ), false );

	typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( );
	typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( );

	for ( ; itB < B.end ( ); ++ itB, ++ itA )
		* itA = * itA ^ * itB;

	return A;
}

/**
 * \brief
 * Support for xor operator.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the first source instance
 * \param B the second source instance
 *
 * \return new vector of booleans with each bit is result of xor operation between respective bits in A and B instances
 */
template < class ... Ts >
ext::vector < bool, Ts ... > operator ^ ( ext::vector < bool, Ts ... > A, const ext::vector < bool, Ts ... > & B ) {
	A ^= B;
	return A;
}

/**
 * \brief
 * Support for not operator.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the source instance
 *
 * \return new vector of booleans with each bit from the source instance inverted
 */
template < class ... Ts >
ext::vector < bool, Ts ... > operator ~ ( ext::vector < bool, Ts ... > A ) {
	A.flip ( );
	return A;
}

/**
 * \brief
 * Support for assigning bit shift to the left operator. The operator is intended to look at the vector of booleans as on the number where lower indexes represent less significant bits and higher indexes represent more significant bits. Therefore the shift is moving values on lower indexes to higher indexes. The size of the vector is unchanged.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the source instance
 * \param dist the distance to shift by
 *
 * \return modified A instance with each bit moved by dist positions to higher indexes
 */
template < class ... Ts >
ext::vector < bool, Ts ... > & operator <<= ( ext::vector < bool, Ts ... > & A, size_t dist ) {
/*	if ( A.size ( ) == 0 )
		return A;

	size_t distBlocks = dist / vectorBoolInternalTypeInBits;
	size_t distWithin = dist % vectorBoolInternalTypeInBits;
	size_t backDist = vectorBoolInternalTypeInBits - distWithin;

	// shift blocks if needed
	if ( distBlocks ) {
		// simulate behavior of reverse iterator
		auto itAReverse = A.end ( ) - 1;
		auto itASource = itAReverse;
		itASource._M_p -= distBlocks;

		while ( itASource >= A.begin ( ) )
			* ( itAReverse._M_p -- ) = * ( itASource._M_p -- );

		while ( itAReverse >= A.begin ( ) )
			* ( itAReverse._M_p -- ) = 0;
	}

	if ( distWithin == 0 )
		return A;

	// shift by the rest dist
	vectorBoolInternalType bits1 { };
	vectorBoolInternalType bits2 { };

	// it might be more clear to iterate from the begining. However this is working nicely
	auto itA = A.begin ( );

	while ( itA < A.end ( ) ) {
		bits2 = * ( itA._M_p );
		* ( itA._M_p ) = * ( itA._M_p ) << distWithin | bits1 >> backDist;
		bits1 = bits2;

		itA._M_p ++;
	}*/

	// c++ compilant
	if ( dist > A.size ( ) ) {
		clear ( A );
	} else {
		typename ext::vector < bool, Ts ... >::reverse_iterator itASource = A.rbegin ( ) + dist;
		typename ext::vector < bool, Ts ... >::reverse_iterator itADest = A.rbegin ( );

		for ( ; itASource < A.rend ( ); ++ itASource, ++ itADest )
			* itADest = * itASource;

		for ( ; itADest < A.rend ( ); ++ itADest )
			* itADest = false;
	}

	return A;
}

/**
 * \brief
 * Support for bit shift to the left operator. The operator is intended to look at the vector of booleans as on the number where lower indexes represent less significant bits and higher indexes represent more significant bits. Therefore the shift is moving values on lower indexes to higher indexes. The size of the vector is unchanged.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the source instance
 * \param dist the distance to shift by
 *
 * \return new instnace of vector of booleans with each bit moved by dist positions to higher indexes
 */
template < class ... Ts >
ext::vector < bool, Ts ... > operator << ( ext::vector < bool, Ts ... > A, size_t dist ) {
	A <<= dist;
	return A;
}

/**
 * \brief
 * Support for assigning bit shift to the right operator. The operator is intended to look at the vector of booleans as on the number where lower indexes represent less significant bits and higher indexes represent more significant bits. Therefore the shift is moving values on higher indexes to lower indexes. The size of the vector is unchanged.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the source instance
 * \param dist the distance to shift by
 *
 * \return modified A instance with each bit moved by dist positions to lower indexes
 */
template < class ... Ts >
ext::vector < bool, Ts ... > & operator >>= ( ext::vector < bool, Ts ... > & A, size_t dist ) {
	/*if ( A.size ( ) == 0 )
		return A;

	size_t distBlocks = dist / vectorBoolInternalTypeInBits;
	size_t distWithin = dist % vectorBoolInternalTypeInBits;
	size_t sizeWithin = A.size ( ) % vectorBoolInternalTypeInBits;
	size_t backDist = vectorBoolInternalTypeInBits - distWithin;

	// upper part of the last word in the ext::vector can contain some garbage so it needs to be cleared
	* ( ( A.end ( ) - 1 )._M_p ) &= getMask ( sizeWithin );

	// shift blocks if needed
	if ( distBlocks ) {
		auto itA = A.begin ( );
		auto itASource = itA;
		itASource._M_p += distBlocks;

		while ( itASource < A.end ( ) )
			* ( itA._M_p ++ ) = * ( itASource._M_p ++ );

		while ( itA < A.end ( ) )
			* ( itA._M_p ++ ) = 0;
	}

	if ( distWithin == 0 )
		return A;

	// shift by the rest dist
	vectorBoolInternalType bits1 { };
	vectorBoolInternalType bits2 { };

	// it might be more clear to iterate from the begining. However this is working nicely
	auto itAReverse = A.end ( ) - 1;

	// simulate behavior of reverse iterator
	while ( itAReverse >= A.begin ( ) ) {
		bits2 = * ( itAReverse._M_p );
		* ( itAReverse._M_p ) = * ( itAReverse._M_p ) >> distWithin | bits1 << backDist;
		bits1 = bits2;

		itAReverse._M_p --;
	}*/

	// c++ compilant
	if ( dist > A.size ( ) ) {
		clear ( A );
	} else {
		typename ext::vector < bool, Ts ... >::iterator itASource = A.begin ( ) + dist;
		typename ext::vector < bool, Ts ... >::iterator itADest = A.begin ( );

		for ( ; itASource < A.end ( ); ++ itASource, ++ itADest )
			* itADest = * itASource;

		for ( ; itADest < A.end ( ); ++ itADest )
			* itADest = false;
	}

	return A;
}

/**
 * \brief
 * Support for bit shift to the right operator. The operator is intended to look at the vector of booleans as on the number where lower indexes represent less significant bits and higher indexes represent more significant bits. Therefore the shift is moving values on higher indexes to lower indexes. The size of the vector is unchanged.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param A the source instance
 * \param dist the distance to shift by
 *
 * \return new instnace of vector of booleans with each bit moved by dist positions to lower indexes
 */
template < class ... Ts >
ext::vector < bool, Ts ... > operator >> ( ext::vector < bool, Ts ... > A, size_t dist ) {
	A >>= dist;
	return A;
}

/**
 * \brief
 * Tests the vector of booleans whether at least one bit inside is set.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param v the tested instance
 *
 * \return true if at least one bit in the vector is set, false othervise
 *
 * //TODO make a method of vector of booleans
 */
template < class ... Ts >
bool any ( const ext::vector < bool, Ts ... > & v ) {
	// c++ implementation-specific
	/*typename ext::vector < bool, Ts ... >::const_iterator itV = v.begin ( );

	size_t sizeWithin = v.size ( ) % vectorBoolInternalTypeInBits;

	while ( itV + 1 < v.end ( ) )
		if ( * ( itV._M_p ++ ) != 0 )
			return true;

	return ( * itV._M_p & getMask ( sizeWithin ) ) != 0;*/

	// c++ compilant
	typename ext::vector < bool, Ts ... >::const_iterator itV = v.begin ( );
	for ( ; itV != v.end ( ); ++ itV )
		if ( * itV )
			return true;

	return false;
}

/**
 * \brief
 * Sets all bits in the vector of booleans.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param v the modified instance
 *
 * //TODO make a method of vector of booleans
 */
template < class ... Ts >
void fill ( ext::vector < bool, Ts ... > & v ) {
	// c++ implementation-specific
	/*typename ext::vector < bool, Ts ... >::iterator itV = v.begin ( );

	while ( itV < v.end ( ) )
		* ( itV._M_p ++ ) = ~ vectorBoolInternalType { };*/

	// c++ compilant
	typename ext::vector < bool, Ts ... >::iterator itV = v.begin ( );
	for ( ; itV != v.end ( ); ++ itV )
		* itV = true;
}

/**
 * \brief
 * Clears all bits in the vector of booleans.
 *
 * \tparam Ts ... additional parameters of vector of booleans
 *
 * \param v the modified instance
 *
 * //TODO make a method of vector of booleans
 */
template < class ... Ts >
void clear ( ext::vector < bool, Ts ... > & v ) {
	// c++ implementation-specific
	/* typename ext::vector < bool, Ts ... >::iterator itV = v.begin ( );

	while ( itV < v.end ( ) )
		* ( itV._M_p ++ ) = 0;*/

	// c++ compilant
	typename ext::vector < bool, Ts ... >::iterator itV = v.begin ( );
	for ( ; itV != v.end ( ); ++ itV )
		* itV = false;
}

} /* namespace ext */

