// -*-c++-*-
// vim: set ft=cpp:

/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#pragma once

#include <algorithm>
#include <iterator>
#include <memory>
#include <utility>

#include <cm/ranges>
#include <cm/type_traits>
#include <cmext/iterator>
#include <cmext/type_traits>

#if defined(__SUNPRO_CC) && defined(__sparc)
#  include <list>
#  include <string>
#  include <vector>
#endif

namespace cm {

#if defined(__SUNPRO_CC) && defined(__sparc)
// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
// templates with constraints.
// So, on this platform, use only simple templates.
#  define APPEND_TWO(C1, C2)                                                  \
    template <typename T, typename U>                                         \
    void append(C1<std::unique_ptr<T>>& v, C2<std::unique_ptr<U>>&& r)        \
    {                                                                         \
      std::transform(                                                         \
        r.begin(), r.end(), std::back_inserter(v),                            \
        [](std::unique_ptr<U>& item) { return std::move(item); });            \
      r.clear();                                                              \
    }                                                                         \
                                                                              \
    template <typename T, typename U>                                         \
    void append(C1<T*>& v, C2<std::unique_ptr<U>> const& r)                   \
    {                                                                         \
      std::transform(                                                         \
        r.begin(), r.end(), std::back_inserter(v),                            \
        [](const std::unique_ptr<U>& item) { return item.get(); });           \
    }

#  define APPEND_ONE(C)                                                       \
    template <typename T, typename InputIt,                                   \
              cm::enable_if_t<cm::is_input_iterator<InputIt>::value, int> =   \
                0>                                                            \
    void append(C<T>& v, InputIt first, InputIt last)                         \
    {                                                                         \
      v.insert(v.end(), first, last);                                         \
    }                                                                         \
                                                                              \
    template <typename T, typename Range,                                     \
              cm::enable_if_t<cm::is_input_range<Range>::value, int> = 0>     \
    void append(C<T>& v, Range const& r)                                      \
    {                                                                         \
      v.insert(v.end(), r.begin(), r.end());                                  \
    }

#  define APPEND(C)                                                           \
    APPEND_TWO(C, C)                                                          \
    APPEND_ONE(C)

#  define APPEND_MIX(C1, C2)                                                  \
    APPEND_TWO(C1, C2)                                                        \
    APPEND_TWO(C2, C1)

// For now, manage only support for std::vector, std::list, and
// std::basic_string. Other sequential container support can be added if
// needed.
APPEND(std::vector)
APPEND(std::list)
APPEND(std::basic_string)
APPEND_MIX(std::vector, std::list)
APPEND_MIX(std::vector, std::basic_string)
APPEND_MIX(std::list, std::basic_string)

#  undef APPEND
#  undef APPEND_MIX
#  undef APPEND_TWO
#  undef APPEND_ONE

#else

template <
  typename Container1, typename Container2,
  cm::enable_if_t<
    cm::is_sequence_container<Container1>::value &&
      cm::is_unique_ptr<typename Container1::value_type>::value &&
      cm::is_unique_ptr<typename Container2::value_type>::value &&
      std::is_convertible<typename Container2::value_type::pointer,
                          typename Container1::value_type::pointer>::value,
    int> = 0>
void append(Container1& v, Container2&& r)
{
  std::transform(
    r.begin(), r.end(), std::back_inserter(v),
    [](typename Container2::value_type& item) { return std::move(item); });
  r.clear();
}

template <typename Container1, typename Container2,
          cm::enable_if_t<
            cm::is_sequence_container<Container1>::value &&
              std::is_pointer<typename Container1::value_type>::value &&
              cm::is_unique_ptr<typename Container2::value_type>::value &&
              std::is_convertible<typename Container2::value_type::pointer,
                                  typename Container1::value_type>::value,
            int> = 0>
#  if defined(__SUNPRO_CC)
void append(Container1& v, Container2 const& r, detail::overload_selector<0>)
#  else
void append(Container1& v, Container2 const& r)
#  endif
{
  std::transform(
    r.begin(), r.end(), std::back_inserter(v),
    [](typename Container2::value_type const& item) { return item.get(); });
}

template <
  typename Container, typename InputIt,
  cm::enable_if_t<
    cm::is_sequence_container<Container>::value &&
      cm::is_input_iterator<InputIt>::value &&
      std::is_convertible<typename std::iterator_traits<InputIt>::value_type,
                          typename Container::value_type>::value,
    int> = 0>
void append(Container& v, InputIt first, InputIt last)
{
  v.insert(v.end(), first, last);
}

template <typename Container, typename Range,
          cm::enable_if_t<
            cm::is_sequence_container<Container>::value &&
              cm::is_input_range<Range>::value &&
              !cm::is_unique_ptr<typename Container::value_type>::value &&
              !cm::is_unique_ptr<typename Range::value_type>::value &&
              std::is_convertible<typename Range::value_type,
                                  typename Container::value_type>::value,
            int> = 0>
#  if defined(__SUNPRO_CC)
void append(Container& v, Range const& r, detail::overload_selector<1>)
#  else
void append(Container& v, Range const& r)
#  endif
{
  v.insert(v.end(), r.begin(), r.end());
}

#  if defined(__SUNPRO_CC)
template <typename T, typename U>
void append(T& v, U const& r)
{
  cm::append(v, r, detail::overload_selector<1>{});
}
#  endif
#endif

#if defined(__SUNPRO_CC)
template <typename Iterator, typename Key>
auto contains(Iterator first, Iterator last, Key const& key,
              detail::overload_selector<1>) -> decltype(first->first == key)
#else
template <typename Iterator, typename Key,
          cm::enable_if_t<
            cm::is_input_iterator<Iterator>::value &&
              std::is_convertible<Key,
                                  typename std::iterator_traits<
                                    Iterator>::value_type::first_type>::value,
            int> = 0>
bool contains(Iterator first, Iterator last, Key const& key)
#endif
{
  return std::find_if(
           first, last,
           [&key](
             typename std::iterator_traits<Iterator>::value_type const& item) {
             return item.first == key;
           }) != last;
}

#if defined(__SUNPRO_CC)
template <typename Iterator, typename Key>
bool contains(Iterator first, Iterator last, Key const& key,
              detail::overload_selector<0>)
#else
template <
  typename Iterator, typename Key,
  cm::enable_if_t<
    cm::is_input_iterator<Iterator>::value &&
      std::is_convertible<
        Key, typename std::iterator_traits<Iterator>::value_type>::value,
    int> = 0>
bool contains(Iterator first, Iterator last, Key const& key)
#endif
{
  return std::find(first, last, key) != last;
}

#if defined(__SUNPRO_CC)
template <typename Iterator, typename Key>
bool contains(Iterator first, Iterator last, Key const& key)
{
  return contains(first, last, key, detail::overload_selector<1>{});
}
#endif

#if defined(__SUNPRO_CC)
template <typename Range, typename Key>
auto contains(Range const& range, Key const& key,
              detail::overload_selector<1>) -> decltype(range.find(key) !=
                                                        range.end())
#else
template <
  typename Range, typename Key,
  cm::enable_if_t<cm::is_associative_container<Range>::value ||
                    cm::is_unordered_associative_container<Range>::value,
                  int> = 0>
bool contains(Range const& range, Key const& key)
#endif
{
  return range.find(key) != range.end();
}

#if defined(__SUNPRO_CC)
template <typename Range, typename Key>
bool contains(Range const& range, Key const& key, detail::overload_selector<0>)
#else
template <
  typename Range, typename Key,
  cm::enable_if_t<cm::is_input_range<Range>::value &&
                    !(cm::is_associative_container<Range>::value ||
                      cm::is_unordered_associative_container<Range>::value),
                  int> = 0>
bool contains(Range const& range, Key const& key)
#endif
{
  return std::find(std::begin(range), std::end(range), key) != std::end(range);
}

#if defined(__SUNPRO_CC)
template <typename Range, typename Key>
bool contains(Range const& range, Key const& key)
{
  return contains(range, key, detail::overload_selector<1>{});
}
#endif

template <
  typename Range,
  cm::enable_if_t<cm::is_associative_container<Range>::value ||
                    cm::is_unordered_associative_container<Range>::value,
                  int> = 0>
std::vector<typename Range::key_type> keys(Range const& range)
{
#if defined(CMake_HAVE_CXX_RANGES)
  using key_type = typename Range::key_type;

#  if __cplusplus >= 202302L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202302L)
  return std::vector<key_type>{ std::from_range, std::views::keys(range) };
#  else
  auto view = std::views::keys(range);
  return std::vector<key_type>{ view.begin(), view.end() };
#  endif
#else
  return cm::views::keys(range);
#endif
}

template <
  typename Range,
  cm::enable_if_t<cm::is_associative_container<Range>::value ||
                    cm::is_unordered_associative_container<Range>::value,
                  int> = 0>
std::vector<typename Range::mapped_type> values(Range const& range)
{
#if defined(CMake_HAVE_CXX_RANGES)
  using value_type = typename Range::mapped_type;

#  if __cplusplus >= 202302L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202302L)
  return std::vector<value_type>{ std::from_range, std::views::values(range) };
#  else
  auto view = std::views::values(range);
  return std::vector<value_type>{ view.begin(), view.end() };
#  endif
#else
  return cm::views::values(range);
#endif
}

// sequence containers with std::pair<> or std::tuple<> as elements
template <typename Range,
          cm::enable_if_t<cm::is_sequence_container<Range>::value &&
                            cm::is_tuple<1, typename Range::value_type>::value,
                          int> = 0>
std::vector<typename std::tuple_element<0, typename Range::value_type>::type>
keys(Range const& range)
{
#if defined(CMake_HAVE_CXX_RANGES)
  using key_type =
    typename std::tuple_element<0, typename Range::value_type>::type;

#  if __cplusplus >= 202302L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202302L)
  return std::vector<key_type>{ std::from_range, std::views::keys(range) };
#  else
  auto view = std::views::keys(range);
  return std::vector<key_type>{ view.begin(), view.end() };
#  endif
#else
  return cm::views::keys(range);
#endif
}

template <typename Range,
          cm::enable_if_t<cm::is_sequence_container<Range>::value &&
                            cm::is_tuple<2, typename Range::value_type>::value,
                          int> = 0>
std::vector<typename std::tuple_element<1, typename Range::value_type>::type>
values(Range const& range)
{
#if defined(CMake_HAVE_CXX_RANGES)
  using value_type =
    typename std::tuple_element<1, typename Range::value_type>::type;

#  if __cplusplus >= 202302L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202302L)
  return std::vector<value_type>{ std::from_range, std::views::values(range) };
#  else
  auto view = std::views::values(range);
  return std::vector<value_type>{ view.begin(), view.end() };
#  endif
#else
  return cm::views::values(range);
#endif
}

} // namespace cm
