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

#include <algorithm>
#include <list>

namespace mrpt::containers
{
/** This class implements a STL container with features of both, a std::set and
 * a std::list.
 * \note Defined in #include <mrpt/containers/list_searchable.h>
 * \ingroup mrpt_containers_grp
 */
template <class T>
class list_searchable : public std::list<T>
{
   public:
	void insert(const T& o) { std::list<T>::push_back(o); }
	typename std::list<T>::iterator find(const T& i)
	{
		return std::find(std::list<T>::begin(), std::list<T>::end(), i);
	}

	typename std::list<T>::const_iterator find(const T& i) const
	{
		return std::find(std::list<T>::begin(), std::list<T>::end(), i);
	}

	/** Finds an element in a list of smart pointers, having "->pointer()", such
	 * as it matches a given plain pointer "ptr". */
	template <typename PTR>
	typename std::list<T>::iterator find_ptr_to(const PTR ptr)
	{
		for (auto it = std::list<T>::begin(); it != std::list<T>::end(); it++)
			if (it->get() == ptr) return it;
		return std::list<T>::end();
	}

	/** Finds an element in a list of smart pointers, having "->pointer()", such
	 * as it matches a given plain pointer "ptr". */
	template <typename PTR>
	typename std::list<T>::const_iterator find_ptr_to(const PTR ptr) const
	{
		for (typename std::list<T>::const_iterator it = std::list<T>::begin();
			 it != std::list<T>::end(); it++)
			if (it->pointer() == ptr) return it;
		return std::list<T>::end();
	}
};
}  // namespace mrpt::containers
