/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2023, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#include "rtti-precomp.h"  // Precompiled headers
//
#include <mrpt/rtti/CListOfClasses.h>

#include <algorithm>
#include <cctype>
#include <functional>
#include <locale>
#include <sstream>

using namespace mrpt::rtti;

bool CListOfClasses::containsDerivedFrom(
	const mrpt::rtti::TRuntimeClassId* id) const
{
	for (const auto& i : data)
		if (i->derivedFrom(id)) return true;
	return false;
}

std::string CListOfClasses::asString() const
{
	std::string s;
	unsigned int cnt = 0;
	for (const auto& i : data)
	{
		if (cnt++ != 0) s += ", ";
		s += std::string(i->className);
	}
	return s;
}

// trim from start
namespace
{
inline std::string& ltrim(std::string& s)
{
	s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](const char c) {
				return !std::isspace(c);
			}));
	return s;
}

// trim from end
inline std::string& rtrim(std::string& s)
{
	s.erase(
		std::find_if(
			s.rbegin(), s.rend(), [](const char c) { return !std::isspace(c); })
			.base(),
		s.end());
	return s;
}

// trim from both ends
inline std::string& trim(std::string& s) { return ltrim(rtrim(s)); }
}  // namespace

void CListOfClasses::fromString(const std::string& s)
{
	MRPT_TRY_START

	data.clear();
	std::stringstream ss(s);
	std::string lin;
	while (std::getline(ss, lin, ','))
	{
		lin = trim(lin);
		const TRuntimeClassId* id = findRegisteredClass(lin);
		ASSERTMSG_(
			id != nullptr, format("Unknown class name: %s", lin.c_str()));
		this->insert(id);
	}

	MRPT_TRY_END
}
