156 lines
4.8 KiB
C++
156 lines
4.8 KiB
C++
#pragma once
|
|
|
|
#include "tl/detail/prologue.h"
|
|
#include <tl/algorithm.h>
|
|
#include <tl/utility.h>
|
|
#include <tl/type_traits.h>
|
|
|
|
namespace tl
|
|
{
|
|
namespace detail
|
|
{
|
|
// associative containers (ordered & unordered) [maps, unordered_maps, multimaps, unordered_multimaps ...]
|
|
template <typename C, typename Key>
|
|
auto find(std::true_type, C& c, const Key& key) noexcept -> decltype(c.begin())
|
|
{
|
|
return c.find(key);
|
|
}
|
|
|
|
// sequence containers [array, vector, dequeue, forward_list, list, ...]
|
|
template <typename C, typename T>
|
|
auto find(std::false_type, C& c, const T& value) noexcept -> decltype(c.begin())
|
|
{
|
|
return eastl::find(tl::begin(c), tl::end(c), value);
|
|
}
|
|
} // namespace detail
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename C, typename T>
|
|
auto find(C& c, const T& value) noexcept -> decltype(c.begin())
|
|
{
|
|
return detail::find(is_associative_container<C>{}, c, value);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace detail
|
|
{
|
|
// associative containers (ordered & unordered) [maps, unordered_maps, multimaps, unordered_multimaps ...]
|
|
template <typename C, typename Key>
|
|
auto cfind(std::true_type, const C& c, const Key& key) noexcept -> decltype(c.cbegin())
|
|
{
|
|
return c.find(key);
|
|
}
|
|
|
|
// sequence containers [array, vector, dequeue, forward_list, list, ...]
|
|
template <typename C, typename T>
|
|
auto cfind(std::false_type, const C& c, const T& value) noexcept -> decltype(c.cbegin())
|
|
{
|
|
return eastl::find(tl::cbegin(c), tl::cend(c), value);
|
|
}
|
|
} // namespace detail
|
|
|
|
|
|
template <typename C, typename T>
|
|
auto cfind(const C& c, const T& value) noexcept -> decltype(c.cbegin())
|
|
{
|
|
return detail::cfind(is_associative_container<C>{}, c, value);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace detail
|
|
{
|
|
// associative containers (ordered) [maps, multimaps ...]
|
|
template <typename C, typename Key>
|
|
auto rfind(std::true_type, C& c, const Key& key) noexcept -> decltype(c.rbegin())
|
|
{
|
|
auto forward_iterator = c.find(key);
|
|
return tl::make_reverse_iterator(forward_iterator);
|
|
}
|
|
|
|
// sequence containers [array, vector, dequeue, list, ...]
|
|
template <typename C, typename T>
|
|
auto rfind(std::false_type, C& c, const T& value) noexcept -> decltype(c.rbegin())
|
|
{
|
|
return eastl::find(tl::rbegin(c), tl::rend(c), value);
|
|
}
|
|
} // namespace detail
|
|
|
|
template <typename C, typename T>
|
|
auto rfind(C& c, const T& value) noexcept -> decltype(c.rbegin())
|
|
{
|
|
return detail::rfind(is_associative_container<C>{}, c, value);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace detail
|
|
{
|
|
// associative containers (ordered) [maps, multimaps ...]
|
|
template <typename C, typename Key>
|
|
auto crfind(std::true_type, const C& c, const Key& key) noexcept -> decltype(c.crbegin())
|
|
{
|
|
auto forward_iterator = c.find(key);
|
|
return tl::make_reverse_iterator(forward_iterator);
|
|
}
|
|
|
|
// sequence containers [array, vector, dequeue, forward_list, list, ...]
|
|
template <typename C, typename T>
|
|
auto crfind(std::false_type, const C& c, const T& value) noexcept -> decltype(c.crbegin())
|
|
{
|
|
return eastl::find(tl::rbegin(c), tl::rend(c), value);
|
|
}
|
|
} // namespace detail
|
|
|
|
template <typename C, typename T>
|
|
auto crfind(const C& c, const T& value) noexcept -> decltype(c.crbegin())
|
|
{
|
|
return detail::rfind(is_associative_container<C>{}, c, value);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename C, typename UnaryPredicate>
|
|
auto find_if(C& c, UnaryPredicate&& p) noexcept -> decltype(c.begin())
|
|
{
|
|
return eastl::find_if(tl::begin(c), tl::end(c), std::forward<UnaryPredicate>(p));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename C, typename UnaryPredicate>
|
|
auto cfind_if(const C& c, UnaryPredicate&& p) noexcept -> decltype(c.cbegin())
|
|
{
|
|
return eastl::find_if(tl::cbegin(c), tl::cend(c), std::forward<UnaryPredicate>(p));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename C, typename UnaryPredicate>
|
|
auto rfind_if(C& c, UnaryPredicate&& p) noexcept -> decltype(c.rbegin())
|
|
{
|
|
return eastl::find_if(tl::rbegin(c), tl::rend(c), std::forward<UnaryPredicate>(p));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename C, typename UnaryPredicate>
|
|
auto crfind_if(const C& c, UnaryPredicate&& p) noexcept -> decltype(c.crbegin())
|
|
{
|
|
return eastl::find_if(tl::crbegin(c), tl::crend(c), std::forward<UnaryPredicate>(p));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename C, typename UnaryPredicate>
|
|
auto find_if_not(C& c, UnaryPredicate&& q) noexcept -> decltype(tl::begin(c))
|
|
{
|
|
return eastl::find_if(tl::begin(c), tl::end(c), std::forward<UnaryPredicate>(q));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
}
|