Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
tuple.hpp 2.38 KiB
/*
 * tuple.hpp
 *
 * Created on: Apr 1, 2013
 * Author: Jan Travnicek
 */

#ifndef __TUPLE_HPP_
#define __TUPLE_HPP_

namespace std {

template<int I, class Tuple>
struct operator_shift_left_impl;

template<int I, class Tuple>
struct operator_shift_left_impl {
	static void operator_shift_left(ostream& out, const Tuple& t) {
		operator_shift_left_impl<I - 1, Tuple>::operator_shift_left(out, t);
		out << ", " << get<I>(t);
	}
};

template<class Tuple>
struct operator_shift_left_impl<0, Tuple> {
	static void operator_shift_left(ostream& out, const Tuple& t) {
		out << get<0>(t);
	}
};

template< class... Ts>
std::ostream& operator<<(std::ostream& out, const std::tuple<Ts...>& tuple) {
	out << "(";
	operator_shift_left_impl<tuple_size<std::tuple<Ts...>>::value - 1, std::tuple<Ts...>>::operator_shift_left(out, tuple);
	out << ")";
	return out;
}

template < int I, typename Tuple >
struct compareTupleHelper;

template < int I, typename Tuple >
struct compareTupleHelper {
	static int compHelp ( const Tuple & t1, const Tuple & t2 ) {
		int res = compareTupleHelper < I - 1, Tuple >::compHelp ( t1, t2 );

		if ( res != 0 ) return res;

		static compare < typename std::decay < typename tuple_element < I, Tuple >::type >::type > comp;
		return comp ( std::get < I > ( t1 ), std::get < I > ( t2 ) );
	}

};

template < class Tuple >
struct compareTupleHelper < 0, Tuple > {
	static int compHelp ( const Tuple & t1, const Tuple & t2 ) {
		static compare < typename std::decay < typename tuple_element < 0, Tuple >::type >::type > comp;
		return comp ( std::get < 0 > ( t1 ), std::get < 0 > ( t2 ) );
	}

};

template < typename ... Ts >
struct compare < tuple < Ts ... > > {
	int operator ()( const tuple < Ts ... > & first, const tuple < Ts ... > & second ) const {
		return compareTupleHelper < tuple_size < std::tuple < Ts ... > >::value - 1, std::tuple < Ts ... > >::compHelp ( first, second );
	}

};

template < class ... Ts >
string to_string ( const std::tuple < Ts ... > & value ) {
	std::stringstream ss;
	ss << value;
	return ss.str();
}

template < class Type, int size, class ... Types >
struct TupleBuilder;

template < class Type, class ... Types >
struct TupleBuilder < Type, 0, Types ... > {
	typedef std::tuple < Types ... > type;
};

template < class Type, int n, class ... Types >
struct TupleBuilder : public TupleBuilder < Type, n - 1, Type, Types ... > {
};

} /* namespace std */

#endif /* __TUPLE_HPP_ */