/*
 * typeinfo.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: Apr 1, 2013
 * Author: Jan Travnicek
 */

#ifndef __TYPEINFO_HPP_
#define __TYPEINFO_HPP_

#include <typeinfo>

#include <extensions/container/string.hpp>

#include "typeindex.h"

namespace ext {

/**
 * \brief
 * Overload of to_string function. For type specified by template parameter.
 *
 * Specialisation for class types. Can handle incomplete types.
 *
 * \param value the type_index to be converted to string
 *
 * \return string representation
 */
template < class T >
std::string to_string ( ) {
	if constexpr ( std::is_class < T >::value ) {
		std::string res = ext::to_string ( ext::type_index ( typeid ( T * ) ) ); // handle even incomplete class types
		res.pop_back ( ); // to erase extra pointer
		return res;
	} else {
		return ext::to_string ( ext::type_index ( typeid ( T ) ) );
	}
}

/**
 * \brief
 * Compares two types specified by their string names not looking at template params and unspecified segments.
 *
 * Example
 * foo < aaa >::bb::cc is equal to foo::::cc
 */
bool is_same_type ( const std::string & first, const std::string & second );
bool are_same_types ( const std::vector < std::string > & first, const std::vector < std::string > & second );

template < typename T >
bool is_same_type ( const std::string & name ) {
	std::string ret = to_string < T > ( );
	return is_same_type ( ret, name );
}

std::string erase_template_info ( std::string str );
ext::vector < std::string > get_template_info ( const std::string & str );

} /* namespace ext */

#endif /* __TYPEINFO_HPP_ */
