/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */

#pragma once

#include "cmConfigure.h" // IWYU pragma: keep

#include <algorithm>
#include <cstddef>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>

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

#include "cmValue.h"

template <typename T>
class BT;

/**
 * CMake lists management
 * A CMake list is a string where list elements are separated by the ';'
 * character.
 *
 * For all operations, input arguments (single value like cm::string_view or
 * multiple values specified through pair of iterators) are, by default,
 * expanded. The expansion can be controlled by the cmList::ExpandElements
 * option.
 *
 * There ate some exceptions to this rule:
 *  * When the input argument is a cmList instance, the value is not expanded.
 *  * The following methods do not expand their argument: cmList::push_back,
 *    cmList::emplace and cmList::emplace_back.
 */

class cmList
{
public:
  using container_type = std::vector<std::string>;

  using value_type = container_type::value_type;
  using allocator_type = container_type::allocator_type;
  using index_type = std::ptrdiff_t;
  using size_type = container_type::size_type;
  using difference_type = container_type::difference_type;
  using reference = container_type::reference;
  using const_reference = container_type::const_reference;
  using iterator = container_type::iterator;
  using const_iterator = container_type::const_iterator;
  using reverse_iterator = container_type::reverse_iterator;
  using const_reverse_iterator = container_type::const_reverse_iterator;

  static const size_type npos = static_cast<size_type>(-1);

  static cm::string_view element_separator;

  enum class EmptyElements
  {
    No,
    Yes,
  };
  enum class ExpandElements
  {
    No,
    Yes,
  };

  cmList() = default;
  cmList(const cmList&) = default;
  cmList(cmList&&) = default;

  cmList(cm::string_view value,
         ExpandElements expandElements = ExpandElements::Yes,
         EmptyElements emptyElements = EmptyElements::No)
  {
    this->assign(value, expandElements, emptyElements);
  }
  cmList(cm::string_view value, EmptyElements emptyElements)
    : cmList(value, ExpandElements::Yes, emptyElements)
  {
  }
  cmList(std::string const& value,
         ExpandElements expandElements = ExpandElements::Yes,
         EmptyElements emptyElements = EmptyElements::No)
  {
    this->assign(value, expandElements, emptyElements);
  }
  cmList(std::string const& value, EmptyElements emptyElements)
    : cmList(value, ExpandElements::Yes, emptyElements)
  {
  }
  cmList(cmValue list, ExpandElements expandElements = ExpandElements::Yes,
         EmptyElements emptyElements = EmptyElements::No)
  {
    if (list) {
      this->assign(*list, expandElements, emptyElements);
    }
  }
  cmList(cmValue list, EmptyElements emptyElements)
    : cmList(list, ExpandElements::Yes, emptyElements)
  {
  }
  template <typename InputIterator>
  cmList(InputIterator first, InputIterator last,
         ExpandElements expandElements = ExpandElements::Yes,
         EmptyElements emptyElements = EmptyElements::No)
  {
    this->assign(first, last, expandElements, emptyElements);
  }
  template <typename InputIterator>
  cmList(InputIterator first, InputIterator last, EmptyElements emptyElements)
    : cmList(first, last, ExpandElements::Yes, emptyElements)
  {
  }
  cmList(const container_type& init,
         ExpandElements expandElements = ExpandElements::Yes,
         EmptyElements emptyElements = EmptyElements::No)
    : cmList(init.begin(), init.end(), expandElements, emptyElements)
  {
  }
  cmList(const container_type& init, EmptyElements emptyElements)
    : cmList(init, ExpandElements::Yes, emptyElements)
  {
  }
  cmList(container_type&& init,
         ExpandElements expandElements = ExpandElements::Yes,
         EmptyElements emptyElements = EmptyElements::No)
    : cmList(std::make_move_iterator(init.begin()),
             std::make_move_iterator(init.end()), expandElements,
             emptyElements)
  {
    init.clear();
  }
  cmList(container_type&& init, EmptyElements emptyElements)
    : cmList(std::move(init), ExpandElements::Yes, emptyElements)
  {
  }
  cmList(std::initializer_list<std::string> init) { this->assign(init); }

  ~cmList() = default;

  cmList& operator=(const cmList&) = default;
  cmList& operator=(cmList&&) = default;

  cmList& operator=(cm::string_view value)
  {
    this->assign(value);
    return *this;
  }
  cmList& operator=(std::string const& value)
  {
    this->assign(value);
    return *this;
  }
  cmList& operator=(cmValue value)
  {
    if (value) {
      this->operator=(*value);
    } else {
      this->clear();
    }

    return *this;
  }

  cmList& operator=(const container_type& init)
  {
    this->assign(init);
    return *this;
  }
  cmList& operator=(container_type&& init)
  {
    this->assign(std::move(init));

    return *this;
  }

  cmList& operator=(std::initializer_list<std::string> init)
  {
    this->assign(init);
    return *this;
  }

  void assign(cm::string_view value,
              ExpandElements expandElements = ExpandElements::Yes,
              EmptyElements emptyElements = EmptyElements::No)
  {
    this->clear();
    this->append(value, expandElements, emptyElements);
  }
  void assign(cm::string_view value, EmptyElements emptyElements)
  {
    this->assign(value, ExpandElements::Yes, emptyElements);
  }
  void assign(std::string const& value,
              ExpandElements expandElements = ExpandElements::Yes,
              EmptyElements emptyElements = EmptyElements::No)
  {
    this->clear();
    this->append(value, expandElements, emptyElements);
  }
  void assign(std::string const& value, EmptyElements emptyElements)
  {
    this->assign(value, ExpandElements::Yes, emptyElements);
  }
  void assign(cmValue value,
              ExpandElements expandElements = ExpandElements::Yes,
              EmptyElements emptyElements = EmptyElements::No)
  {
    if (value) {
      this->assign(*value, expandElements, emptyElements);
    } else {
      this->clear();
    }
  }
  void assign(cmValue value, EmptyElements emptyElements)
  {
    this->assign(value, ExpandElements::Yes, emptyElements);
  }
  template <typename InputIterator>
  void assign(InputIterator first, InputIterator last,
              ExpandElements expandElements = ExpandElements::Yes,
              EmptyElements emptyElements = EmptyElements::No)
  {
    this->clear();
    this->append(first, last, expandElements, emptyElements);
  }
  template <typename InputIterator>
  void assign(InputIterator first, InputIterator last,
              EmptyElements emptyElements)
  {
    this->assign(first, last, ExpandElements::Yes, emptyElements);
  }
  void assign(const cmList& init,
              ExpandElements expandElements = ExpandElements::No,
              EmptyElements emptyElements = EmptyElements::No)
  {
    this->assign(init.begin(), init.end(), expandElements, emptyElements);
  }
  void assign(const cmList& init, EmptyElements emptyElements)
  {
    this->assign(init, ExpandElements::No, emptyElements);
  }
  void assign(cmList&& init,
              ExpandElements expandElements = ExpandElements::No,
              EmptyElements emptyElements = EmptyElements::No)
  {
    this->assign(std::make_move_iterator(init.begin()),
                 std::make_move_iterator(init.end()), expandElements,
                 emptyElements);
    init.clear();
  }
  void assign(cmList&& init, EmptyElements emptyElements)
  {
    this->assign(std::move(init), ExpandElements::No, emptyElements);
  }
  void assign(const container_type& init,
              ExpandElements expandElements = ExpandElements::Yes,
              EmptyElements emptyElements = EmptyElements::No)
  {
    this->assign(init.begin(), init.end(), expandElements, emptyElements);
  }
  void assign(const container_type& init, EmptyElements emptyElements)
  {
    this->assign(init, ExpandElements::Yes, emptyElements);
  }
  void assign(container_type&& init,
              ExpandElements expandElements = ExpandElements::Yes,
              EmptyElements emptyElements = EmptyElements::No)
  {
    this->assign(std::make_move_iterator(init.begin()),
                 std::make_move_iterator(init.end()), expandElements,
                 emptyElements);
    init.clear();
  }
  void assign(container_type&& init, EmptyElements emptyElements)
  {
    this->assign(std::move(init), ExpandElements::Yes, emptyElements);
  }
  void assign(std::initializer_list<std::string> init)
  {
    this->assign(init.begin(), init.end());
  }

  // Conversions
  std::string to_string() const
  {
    return this->join(cmList::element_separator);
  }

  operator container_type&() & noexcept { return this->Values; }
  operator const container_type&() const& noexcept { return this->Values; }
  operator container_type&&() && noexcept { return std::move(this->Values); }

  // Element access
  reference at(size_type pos) { return this->Values.at(pos); }
  const_reference at(size_type pos) const { return this->Values.at(pos); }

  reference operator[](size_type pos) { return this->Values[pos]; }
  const_reference operator[](size_type pos) const { return this->Values[pos]; }

  reference get_item(index_type pos)
  {
    return this->Values.at(this->ComputeIndex(pos));
  }
  const_reference get_item(index_type pos) const
  {
    return this->Values.at(this->ComputeIndex(pos));
  }

  reference front() { return this->Values.front(); }
  const_reference front() const { return this->Values.front(); }

  reference back() { return this->Values.back(); }
  const_reference back() const { return this->Values.back(); }

  // extract sublist in range [first, last)
  cmList sublist(const_iterator first, const_iterator last) const
  {
    return cmList{ first, last, ExpandElements::No, EmptyElements::Yes };
  }
  // Extract sublist in range [first, last)
  // Throw std::out_of_range if pos is invalid
  cmList sublist(size_type pos = 0, size_type length = npos) const;

  // Returns the list of elements
  // Throw std::out_of_range if any index is invalid
  cmList get_items(std::initializer_list<index_type> indexes) const
  {
    return this->GetItems(
      std::vector<index_type>{ indexes.begin(), indexes.end() });
  }
  template <typename InputIterator>
  cmList get_items(InputIterator first, InputIterator last) const
  {
    return this->GetItems(std::vector<index_type>{ first, last });
  }

  size_type find(cm::string_view value) const;
  size_type find(cmValue value) const
  {
    if (value) {
      return this->find(*value);
    }

    return npos;
  }

  container_type& data() noexcept { return this->Values; }
  const container_type& data() const noexcept { return this->Values; }

  // Iterators
  iterator begin() noexcept { return this->Values.begin(); }
  const_iterator begin() const noexcept { return this->Values.begin(); }
  const_iterator cbegin() const noexcept { return this->Values.cbegin(); }

  iterator end() noexcept { return this->Values.end(); }
  const_iterator end() const noexcept { return this->Values.end(); }
  const_iterator cend() const noexcept { return this->Values.cend(); }

  reverse_iterator rbegin() noexcept { return this->Values.rbegin(); }
  const_reverse_iterator rbegin() const noexcept
  {
    return this->Values.rbegin();
  }
  const_reverse_iterator crbegin() const noexcept
  {
    return this->Values.crbegin();
  }

  reverse_iterator rend() noexcept { return this->Values.rend(); }
  const_reverse_iterator rend() const noexcept { return this->Values.rend(); }
  const_reverse_iterator crend() const noexcept
  {
    return this->Values.crend();
  }

  // Capacity
  bool empty() const noexcept { return this->Values.empty(); }
  size_type size() const noexcept { return this->Values.size(); }

  // Modifiers
  void clear() noexcept { this->Values.clear(); }

  iterator insert(const_iterator pos, cm::string_view value,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::Insert(this->Values, pos, std::string(value),
                          expandElements, emptyElements);
  }
  iterator insert(const_iterator pos, cm::string_view value,
                  EmptyElements emptyElements)
  {
    return this->insert(pos, value, ExpandElements::Yes, emptyElements);
  }
  iterator insert(const_iterator pos, std::string const& value,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::Insert(this->Values, pos, value, expandElements,
                          emptyElements);
  }
  iterator insert(const_iterator pos, std::string const& value,
                  EmptyElements emptyElements)
  {
    return this->insert(pos, value, ExpandElements::Yes, emptyElements);
  }
  iterator insert(const_iterator pos, cmValue value,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    if (value) {
      return this->insert(pos, *value, expandElements, emptyElements);
    }

    auto delta = std::distance(this->cbegin(), pos);
    return this->begin() + delta;
  }
  iterator insert(const_iterator pos, cmValue value,
                  EmptyElements emptyElements)
  {
    return this->insert(pos, value, ExpandElements::Yes, emptyElements);
  }
  template <typename InputIterator>
  iterator insert(const_iterator pos, InputIterator first, InputIterator last,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::Insert(this->Values, pos, first, last, expandElements,
                          emptyElements);
  }
  template <typename InputIterator>
  iterator insert(const_iterator pos, InputIterator first, InputIterator last,
                  EmptyElements emptyElements)
  {
    return this->insert(pos, first, last, ExpandElements::Yes, emptyElements);
  }
  iterator insert(const_iterator pos, const cmList& values,
                  ExpandElements expandElements = ExpandElements::No,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    return this->insert(pos, values.begin(), values.end(), expandElements,
                        emptyElements);
  }
  iterator insert(const_iterator pos, const cmList& values,
                  EmptyElements emptyElements)
  {
    return this->insert(pos, values, ExpandElements::No, emptyElements);
  }
  iterator insert(const_iterator pos, cmList&& values,
                  ExpandElements expandElements = ExpandElements::No,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    auto result = this->insert(pos, std::make_move_iterator(values.begin()),
                               std::make_move_iterator(values.end()),
                               expandElements, emptyElements);
    values.clear();

    return result;
  }
  iterator insert(const_iterator pos, cmList&& values,
                  EmptyElements emptyElements)
  {
    return this->insert(pos, std::move(values), ExpandElements::No,
                        emptyElements);
  }
  iterator insert(const_iterator pos, const container_type& values,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    return this->insert(pos, values.begin(), values.end(), expandElements,
                        emptyElements);
  }
  iterator insert(const_iterator pos, const container_type& values,
                  EmptyElements emptyElements)
  {
    return this->insert(pos, values, ExpandElements::Yes, emptyElements);
  }
  iterator insert(const_iterator pos, container_type&& values,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    auto result = this->insert(pos, std::make_move_iterator(values.begin()),
                               std::make_move_iterator(values.end()),
                               expandElements, emptyElements);
    values.clear();

    return result;
  }
  iterator insert(const_iterator pos, container_type&& values,
                  EmptyElements emptyElements)
  {
    return this->insert(pos, std::move(values), ExpandElements::Yes,
                        emptyElements);
  }
  iterator insert(const_iterator pos, std::initializer_list<std::string> ilist)
  {
    return this->insert(pos, ilist.begin(), ilist.end());
  }

  iterator append(cm::string_view value,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    return this->insert(this->cend(), value, expandElements, emptyElements);
  }
  iterator append(cm::string_view value, EmptyElements emptyElements)
  {
    return this->append(value, ExpandElements::Yes, emptyElements);
  }
  iterator append(std::string const& value,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    return this->insert(this->cend(), value, expandElements, emptyElements);
  }
  iterator append(std::string const& value, EmptyElements emptyElements)
  {
    return this->append(value, ExpandElements::Yes, emptyElements);
  }
  iterator append(cmValue value,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    if (value) {
      return this->append(*value, expandElements, emptyElements);
    }

    return this->end();
  }
  iterator append(cmValue value, EmptyElements emptyElements)
  {
    return this->append(value, ExpandElements::Yes, emptyElements);
  }
  template <typename InputIterator>
  iterator append(InputIterator first, InputIterator last,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    return this->insert(this->cend(), first, last, expandElements,
                        emptyElements);
  }
  template <typename InputIterator>
  iterator append(InputIterator first, InputIterator last,
                  EmptyElements emptyElements)
  {
    return this->append(first, last, ExpandElements::Yes, emptyElements);
  }
  iterator append(const cmList& values,
                  ExpandElements expandElements = ExpandElements::No,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    return this->append(values.begin(), values.end(), expandElements,
                        emptyElements);
  }
  iterator append(const cmList& values, EmptyElements emptyElements)
  {
    return this->append(values, ExpandElements::No, emptyElements);
  }
  iterator append(cmList&& values,
                  ExpandElements expandElements = ExpandElements::No,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    auto result = this->append(std::make_move_iterator(values.begin()),
                               std::make_move_iterator(values.end()),
                               expandElements, emptyElements);
    values.clear();

    return result;
  }
  iterator append(cmList&& values, EmptyElements emptyElements)
  {
    return this->append(std::move(values), ExpandElements::No, emptyElements);
  }
  iterator append(const container_type& values,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    return this->append(values.begin(), values.end(), expandElements,
                        emptyElements);
  }
  iterator append(const container_type& values, EmptyElements emptyElements)
  {
    return this->append(values, ExpandElements::Yes, emptyElements);
  }
  iterator append(container_type&& values,
                  ExpandElements expandElements = ExpandElements::Yes,
                  EmptyElements emptyElements = EmptyElements::No)
  {
    auto result = this->append(std::make_move_iterator(values.begin()),
                               std::make_move_iterator(values.end()),
                               expandElements, emptyElements);
    values.clear();

    return result;
  }
  iterator append(container_type&& values, EmptyElements emptyElements)
  {
    return this->append(std::move(values), ExpandElements::Yes, emptyElements);
  }
  iterator append(std::initializer_list<std::string> ilist)
  {
    return this->insert(this->cend(), ilist);
  }

  iterator prepend(cm::string_view value,
                   ExpandElements expandElements = ExpandElements::Yes,
                   EmptyElements emptyElements = EmptyElements::No)
  {
    return this->insert(this->cbegin(), value, expandElements, emptyElements);
  }
  iterator prepend(cm::string_view value, EmptyElements emptyElements)
  {
    return this->prepend(value, ExpandElements::Yes, emptyElements);
  }
  iterator prepend(std::string const& value,
                   ExpandElements expandElements = ExpandElements::Yes,
                   EmptyElements emptyElements = EmptyElements::No)
  {
    return this->insert(this->cbegin(), value, expandElements, emptyElements);
  }
  iterator prepend(std::string const& value, EmptyElements emptyElements)
  {
    return this->prepend(value, ExpandElements::Yes, emptyElements);
  }
  iterator prepend(cmValue value,
                   ExpandElements expandElements = ExpandElements::Yes,
                   EmptyElements emptyElements = EmptyElements::No)
  {
    if (value) {
      return this->prepend(*value, expandElements, emptyElements);
    }

    return this->begin();
  }
  iterator prepend(cmValue value, EmptyElements emptyElements)
  {
    return this->prepend(value, ExpandElements::Yes, emptyElements);
  }
  template <typename InputIterator>
  iterator prepend(InputIterator first, InputIterator last,
                   ExpandElements expandElements = ExpandElements::Yes,
                   EmptyElements emptyElements = EmptyElements::No)
  {
    return this->insert(this->cbegin(), first, last, expandElements,
                        emptyElements);
  }
  template <typename InputIterator>
  iterator prepend(InputIterator first, InputIterator last,
                   EmptyElements emptyElements)
  {
    return this->prepend(first, last, ExpandElements::Yes, emptyElements);
  }
  iterator prepend(const cmList& values,
                   ExpandElements expandElements = ExpandElements::No,
                   EmptyElements emptyElements = EmptyElements::No)
  {
    return this->prepend(values.begin(), values.end(), expandElements,
                         emptyElements);
  }
  iterator prepend(const cmList& values, EmptyElements emptyElements)
  {
    return this->prepend(values, ExpandElements::No, emptyElements);
  }
  iterator prepend(cmList&& values,
                   ExpandElements expandElements = ExpandElements::No,
                   EmptyElements emptyElements = EmptyElements::No)
  {
    auto result = this->prepend(std::make_move_iterator(values.begin()),
                                std::make_move_iterator(values.end()),
                                expandElements, emptyElements);
    values.clear();

    return result;
  }
  iterator prepend(cmList&& values, EmptyElements emptyElements)
  {
    return this->prepend(std::move(values), ExpandElements::No, emptyElements);
  }
  iterator prepend(const container_type& values,
                   ExpandElements expandElements = ExpandElements::Yes,
                   EmptyElements emptyElements = EmptyElements::No)
  {
    return this->prepend(values.begin(), values.end(), expandElements,
                         emptyElements);
  }
  iterator prepend(const container_type& values, EmptyElements emptyElements)
  {
    return this->prepend(values, ExpandElements::Yes, emptyElements);
  }
  iterator prepend(container_type&& values,
                   ExpandElements expandElements = ExpandElements::Yes,
                   EmptyElements emptyElements = EmptyElements::No)
  {
    auto result = this->prepend(std::make_move_iterator(values.begin()),
                                std::make_move_iterator(values.end()),
                                expandElements, emptyElements);
    values.clear();

    return result;
  }
  iterator prepend(container_type&& values, EmptyElements emptyElements)
  {
    return this->prepend(std::move(values), ExpandElements::Yes,
                         emptyElements);
  }
  iterator prepend(std::initializer_list<std::string> ilist)
  {
    return this->insert(this->cbegin(), ilist);
  }

  void push_back(std::string const& value) { this->Values.push_back(value); }
  void push_back(cm::string_view value)
  {
    this->Values.push_back(std::string{ value });
  }
  void push_back(std::string&& value)
  {
    this->Values.push_back(std::move(value));
  }

  template <typename... Args>
  iterator emplace(const_iterator pos, Args&&... args)
  {
    return this->Values.emplace(pos, std::forward<Args>(args)...);
  }

  template <typename... Args>
  void emplace_back(Args&&... args)
  {
    this->Values.emplace_back(std::forward<Args>(args)...);
  }

  // Inserts elements in the list
  // Throw std::out_of_range if index is invalid
  template <typename InputIterator>
  cmList& insert_items(index_type index, InputIterator first,
                       InputIterator last,
                       ExpandElements expandElements = ExpandElements::Yes,
                       EmptyElements emptyElements = EmptyElements::No)
  {
    auto const offset =
      static_cast<difference_type>(this->ComputeInsertIndex(index));
    this->insert(this->begin() + offset, first, last, expandElements,
                 emptyElements);
    return *this;
  }
  template <typename InputIterator>
  cmList& insert_items(index_type index, InputIterator first,
                       InputIterator last, EmptyElements emptyElements)
  {
    this->insert(this->begin() + this->ComputeInsertIndex(index), first, last,
                 ExpandElements::Yes, emptyElements);
    return *this;
  }
  cmList& insert_items(index_type index,
                       std::initializer_list<std::string> values)
  {
    return this->insert_items(index, values.begin(), values.end());
  }

  iterator erase(const_iterator pos)
  {
    // convert const_iterator in iterator to please non standard c++11
    // compilers (gcc 4.8 for example)
    auto pos2 =
      this->Values.begin() + std::distance(this->Values.cbegin(), pos);
    return this->Values.erase(pos2);
  }
  iterator erase(const_iterator first, const_iterator last)
  {
    // convert const_iterator in iterator to please non standard c++11
    // compilers (gcc 4.8 for example)
    auto first2 =
      this->Values.begin() + std::distance(this->Values.cbegin(), first);
    auto last2 =
      this->Values.begin() + std::distance(this->Values.cbegin(), last);
    return this->Values.erase(first2, last2);
  }

  void pop_back() { this->Values.pop_back(); }
  void pop_front() { this->Values.erase(this->begin()); }

  // Removes elements from the list
  // Throw std::out_of_range if any index is invalid
  cmList& remove_items(std::initializer_list<index_type> indexes)
  {
    return this->RemoveItems(
      std::vector<index_type>{ indexes.begin(), indexes.end() });
  }
  cmList& remove_items(std::initializer_list<std::string> values)
  {
    return this->RemoveItems(
      std::vector<std::string>{ values.begin(), values.end() });
  }
  template <typename InputIterator>
  cmList& remove_items(InputIterator first, InputIterator last)
  {
    return this->RemoveItems(
      std::vector<typename InputIterator::value_type>{ first, last });
  }

  cmList& remove_duplicates();

  void resize(size_type count) { this->Values.resize(count); }

  enum class FilterMode
  {
    INCLUDE,
    EXCLUDE
  };
  // Includes or removes items from the list
  // Throw std::invalid_argument if regular expression is invalid
  cmList& filter(cm::string_view regex, FilterMode mode);

  cmList& reverse()
  {
    std::reverse(this->Values.begin(), this->Values.end());
    return *this;
  }

  struct SortConfiguration
  {
    enum class OrderMode
    {
      DEFAULT,
      ASCENDING,
      DESCENDING,
    } Order = OrderMode::DEFAULT;

    enum class CompareMethod
    {
      DEFAULT,
      STRING,
      FILE_BASENAME,
      NATURAL,
    } Compare = CompareMethod::DEFAULT;

    enum class CaseSensitivity
    {
      DEFAULT,
      SENSITIVE,
      INSENSITIVE,
    } Case = CaseSensitivity::DEFAULT;

    // declare the default constructor to work-around clang bug
    SortConfiguration();

    SortConfiguration(OrderMode order, CompareMethod compare,
                      CaseSensitivity caseSensitivity)
      : Order(order)
      , Compare(compare)
      , Case(caseSensitivity)
    {
    }
  };
  cmList& sort(const SortConfiguration& config = SortConfiguration{});

  // exception raised on error during transform operations
  class transform_error : public std::runtime_error
  {
  public:
    transform_error(const std::string& error)
      : std::runtime_error(error)
    {
    }
  };

  class TransformSelector
  {
  public:
    using index_type = cmList::index_type;

    // define some structs used as template selector
    struct AT;
    struct FOR;
    struct REGEX;

    virtual ~TransformSelector() = default;

    virtual const std::string& GetTag() = 0;

    // method NEW is used to allocate a selector of the needed type.
    // For example:
    // cmList::TransformSelector::New<AT>({1, 2, 5, 6});
    //  or
    // cmList::TransformSelector::New<REGEX>("^XX.*");
    template <typename Type>
    static std::unique_ptr<TransformSelector> New(
      std::initializer_list<index_type>);
    template <typename Type>
    static std::unique_ptr<TransformSelector> New(
      std::vector<index_type> const&);
    template <typename Type>
    static std::unique_ptr<TransformSelector> New(std::vector<index_type>&&);

    template <typename Type>
    static std::unique_ptr<TransformSelector> New(std::string const&);
    template <typename Type>
    static std::unique_ptr<TransformSelector> New(std::string&&);

  private:
    static std::unique_ptr<TransformSelector> NewAT(
      std::initializer_list<index_type> init);
    static std::unique_ptr<TransformSelector> NewAT(
      std::vector<index_type> const& init);
    static std::unique_ptr<TransformSelector> NewAT(
      std::vector<index_type>&& init);

    static std::unique_ptr<TransformSelector> NewFOR(
      std::initializer_list<index_type> init);
    static std::unique_ptr<TransformSelector> NewFOR(
      std::vector<index_type> const& init);
    static std::unique_ptr<TransformSelector> NewFOR(
      std::vector<index_type>&& init);

    static std::unique_ptr<TransformSelector> NewREGEX(
      std::string const& init);
    static std::unique_ptr<TransformSelector> NewREGEX(std::string&& init);
  };

  enum class TransformAction
  {
    APPEND,
    PREPEND,
    TOLOWER,
    TOUPPER,
    STRIP,
    GENEX_STRIP,
    REPLACE
  };

  // Transforms the list by applying an action
  // Throw std::transform_error is any of arguments specified are invalid
  cmList& transform(TransformAction action,
                    std::unique_ptr<TransformSelector> = {});
  cmList& transform(TransformAction action, std::string const& arg,
                    std::unique_ptr<TransformSelector> = {});
  cmList& transform(TransformAction action, std::string const& arg1,
                    std::string const& arg2,
                    std::unique_ptr<TransformSelector> = {});
  cmList& transform(TransformAction action,
                    std::vector<std::string> const& args,
                    std::unique_ptr<TransformSelector> = {});

  std::string join(cm::string_view glue) const
  {
    return cmList::Join(this->Values, glue);
  }

  void swap(cmList& other) noexcept { this->Values.swap(other.Values); }

  // static members
  // ==============
  // these methods can be used to store CMake list expansion directly in a
  // std::vector.
  static void assign(std::vector<std::string>& container,
                     cm::string_view value,
                     EmptyElements emptyElements = EmptyElements::No)
  {
    container.clear();
    cmList::append(container, value, emptyElements);
  }
  static void assign(std::vector<std::string>& container,
                     std::string const& value,
                     EmptyElements emptyElements = EmptyElements::No)
  {
    container.clear();
    cmList::append(container, value, emptyElements);
  }
  static void assign(std::vector<std::string>& container, cmValue value,
                     EmptyElements emptyElements = EmptyElements::No)
  {
    if (value) {
      cmList::assign(container, *value, emptyElements);
    } else {
      container.clear();
    }
  }
  template <typename InputIterator>
  static void assign(std::vector<std::string>& container, InputIterator first,
                     InputIterator last,
                     EmptyElements emptyElements = EmptyElements::No)
  {
    container.clear();
    cmList::append(container, first, last, emptyElements);
  }

  static std::vector<std::string>::iterator insert(
    std::vector<std::string>& container,
    std::vector<std::string>::const_iterator pos, cm::string_view value,
    EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::Insert(container, pos, std::string(value),
                          ExpandElements::Yes, emptyElements);
  }
  static std::vector<std::string>::iterator insert(
    std::vector<std::string>& container,
    std::vector<std::string>::const_iterator pos, std::string const& value,
    EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::Insert(container, pos, value, ExpandElements::Yes,
                          emptyElements);
  }
  static std::vector<std::string>::iterator insert(
    std::vector<std::string>& container,
    std::vector<std::string>::const_iterator pos, cmValue value,
    EmptyElements emptyElements = EmptyElements::No)
  {
    if (value) {
      return cmList::insert(container, pos, *value, emptyElements);
    }

    auto delta = std::distance(container.cbegin(), pos);
    return container.begin() + delta;
  }
  template <typename InputIterator>
  static std::vector<std::string>::iterator insert(
    std::vector<std::string>& container,
    std::vector<std::string>::const_iterator pos, InputIterator first,
    InputIterator last, EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::Insert(container, pos, first, last, ExpandElements::Yes,
                          emptyElements);
  }

  static std::vector<std::string>::iterator append(
    std::vector<std::string>& container, cm::string_view value,
    EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::insert(container, container.cend(), value, emptyElements);
  }
  static std::vector<std::string>::iterator append(
    std::vector<std::string>& container, std::string const& value,
    EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::insert(container, container.cend(), value, emptyElements);
  }
  static std::vector<std::string>::iterator append(
    std::vector<std::string>& container, cmValue value,
    EmptyElements emptyElements = EmptyElements::No)
  {
    if (value) {
      return cmList::append(container, *value, emptyElements);
    }

    return container.end();
  }
  template <typename InputIterator>
  static std::vector<std::string>::iterator append(
    std::vector<std::string>& container, InputIterator first,
    InputIterator last, EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::insert(container, container.cend(), first, last,
                          emptyElements);
  }

  static std::vector<std::string>::iterator prepend(
    std::vector<std::string>& container, cm::string_view value,
    EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::insert(container, container.cbegin(), value, emptyElements);
  }
  static std::vector<std::string>::iterator prepend(
    std::vector<std::string>& container, std::string const& value,
    EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::insert(container, container.cbegin(), value, emptyElements);
  }
  static std::vector<std::string>::iterator prepend(
    std::vector<std::string>& container, cmValue value,
    EmptyElements emptyElements = EmptyElements::No)
  {
    if (value) {
      return cmList::prepend(container, *value, emptyElements);
    }

    return container.begin();
  }
  template <typename InputIterator>
  static std::vector<std::string>::iterator prepend(
    std::vector<std::string>& container, InputIterator first,
    InputIterator last, EmptyElements emptyElements = EmptyElements::No)
  {
    return cmList::insert(container, container.cbegin(), first, last,
                          emptyElements);
  }

  // The following methods offer the possibility to extend a CMake list
  // but without any intermediate expansion. So the operation is simply a
  // string concatenation with special handling for the CMake list item
  // separator
  static std::string& append(std::string& list, std::string&& value);
  static std::string& append(std::string& list, cm::string_view value);
  template <typename InputIterator>
  static std::string& append(std::string& list, InputIterator first,
                             InputIterator last)
  {
    if (first == last) {
      return list;
    }

    return cmList::append(
      list, cmList::Join(first, last, cmList::element_separator));
  }

  static std::string& prepend(std::string& list, std::string&& value);
  static std::string& prepend(std::string& list, cm::string_view value);
  template <typename InputIterator>
  static std::string& prepend(std::string& list, InputIterator first,
                              InputIterator last)
  {
    if (first == last) {
      return list;
    }

    return cmList::prepend(
      list, cmList::Join(first, last, cmList::element_separator));
  }

  template <typename Range,
            cm::enable_if_t<cm::is_range<Range>::value, int> = 0>
  static std::string to_string(Range const& r)
  {
    return cmList::Join(r, cmList::element_separator);
  }

  // Non-members
  // ===========
  friend inline bool operator==(const cmList& lhs, const cmList& rhs) noexcept
  {
    return lhs.Values == rhs.Values;
  }
  friend inline bool operator!=(const cmList& lhs, const cmList& rhs) noexcept
  {
    return lhs.Values != rhs.Values;
  }

private:
  size_type ComputeIndex(index_type pos, bool boundCheck = true) const;
  size_type ComputeInsertIndex(index_type pos, bool boundCheck = true) const;

  cmList GetItems(std::vector<index_type>&& indexes) const;

  cmList& RemoveItems(std::vector<index_type>&& indexes);
  cmList& RemoveItems(std::vector<std::string>&& items);

  static container_type::iterator Insert(container_type& container,
                                         container_type::const_iterator pos,
                                         std::string&& value,
                                         ExpandElements expandElements,
                                         EmptyElements emptyElements);
  static container_type::iterator Insert(container_type& container,
                                         container_type::const_iterator pos,
                                         const std::string& value,
                                         ExpandElements expandElements,
                                         EmptyElements emptyElements)
  {
    auto tmp = value;
    return cmList::Insert(container, pos, std::move(tmp), expandElements,
                          emptyElements);
  }
  template <typename InputIterator>
  static container_type::iterator Insert(container_type& container,
                                         container_type::const_iterator pos,
                                         InputIterator first,
                                         InputIterator last,
                                         ExpandElements expandElements,
                                         EmptyElements emptyElements)
  {
    auto delta = std::distance(container.cbegin(), pos);

    if (first == last) {
      return container.begin() + delta;
    }

    auto insertPos = container.begin() + delta;
    if (expandElements == ExpandElements::Yes) {
      for (; first != last; ++first) {
        auto size = container.size();
        insertPos = cmList::Insert(container, insertPos, *first,
                                   expandElements, emptyElements);
        insertPos += static_cast<decltype(delta)>(container.size() - size);
      }
    } else {
      for (; first != last; ++first) {
        if (!(*first).empty() || emptyElements == EmptyElements::Yes) {
          insertPos = container.insert(insertPos, *first);
          ++insertPos;
        }
      }
    }

    return container.begin() + delta;
  }

  static std::string const& ToString(std::string const& s) { return s; }
  static std::string ToString(cm::string_view s) { return std::string{ s }; }
  static std::string const& ToString(BT<std::string> const&);

  template <typename Range>
  static std::string Join(Range const& r, cm::string_view glue)
  {
    if (cm::size(r) == 0) {
      return std::string{};
    }

    return cmList::Join(std::begin(r), std::end(r), glue);
  }
  template <typename InputIterator>
  static std::string Join(InputIterator first, InputIterator last,
                          cm::string_view glue)
  {
    if (first == last) {
      return std::string{};
    }

    const auto sep = std::string{ glue };

    std::string joined = cmList::ToString(*first);
    for (auto it = std::next(first); it != last; ++it) {
      joined += sep;
      joined += cmList::ToString(*it);
    }

    return joined;
  }

  container_type Values;
};

// specializations for cmList::TransformSelector allocators
// ========================================================
template <>
inline std::unique_ptr<cmList::TransformSelector>
cmList::TransformSelector::New<cmList::TransformSelector::AT>(
  std::initializer_list<index_type> init)
{
  return cmList::TransformSelector::NewAT(init);
}
template <>
inline std::unique_ptr<cmList::TransformSelector>
cmList::TransformSelector::New<cmList::TransformSelector::AT>(
  std::vector<index_type> const& init)
{
  return cmList::TransformSelector::NewAT(init);
}
template <>
inline std::unique_ptr<cmList::TransformSelector>
cmList::TransformSelector::New<cmList::TransformSelector::AT>(
  std::vector<index_type>&& init)
{
  return cmList::TransformSelector::NewAT(std::move(init));
}

template <>
inline std::unique_ptr<cmList::TransformSelector>
cmList::TransformSelector::New<cmList::TransformSelector::FOR>(
  std::initializer_list<index_type> init)
{
  return cmList::TransformSelector::NewFOR(init);
}
template <>
inline std::unique_ptr<cmList::TransformSelector>
cmList::TransformSelector::New<cmList::TransformSelector::FOR>(
  std::vector<index_type> const& init)
{
  return cmList::TransformSelector::NewFOR(init);
}
template <>
inline std::unique_ptr<cmList::TransformSelector>
cmList::TransformSelector::New<cmList::TransformSelector::FOR>(
  std::vector<index_type>&& init)
{
  return cmList::TransformSelector::NewFOR(std::move(init));
}

template <>
inline std::unique_ptr<cmList::TransformSelector>
cmList::TransformSelector::New<cmList::TransformSelector::REGEX>(
  std::string const& init)
{
  return cmList::TransformSelector::NewREGEX(init);
}
template <>
inline std::unique_ptr<cmList::TransformSelector>
cmList::TransformSelector::New<cmList::TransformSelector::REGEX>(
  std::string&& init)
{
  return cmList::TransformSelector::NewREGEX(std::move(init));
}

// Non-member functions
// ====================
inline std::vector<std::string>& operator+=(std::vector<std::string>& l,
                                            const cmList& r)
{
  l.insert(l.end(), r.begin(), r.end());
  return l;
}
inline std::vector<std::string>& operator+=(std::vector<std::string>& l,
                                            cmList&& r)
{
  std::move(r.begin(), r.end(), std::back_inserter(l));
  r.clear();

  return l;
}

namespace std {
inline void swap(cmList& lhs, cmList& rhs) noexcept
{
  lhs.swap(rhs);
}
} // namespace std

namespace cm {
inline void erase(cmList& list, const std::string& value)
{
  list.erase(std::remove(list.begin(), list.end(), value), list.end());
}

template <typename Predicate>
inline void erase_if(cmList& list, Predicate pred)
{
  list.erase(std::remove_if(list.begin(), list.end(), pred), list.end());
}

//
// Provide a special implementation of cm::append because, in this case,
// expansion must not be applied to the inserted elements
//
#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.
template <typename InputIt,
          cm::enable_if_t<cm::is_input_iterator<InputIt>::value, int> = 0>
void append(cmList& v, InputIt first, InputIt last)
{
  v.append(first, last, cmList::ExpandElements::No);
}

template <typename Range,
          cm::enable_if_t<cm::is_input_range<Range>::value, int> = 0>
void append(cmList& v, Range const& r)
{
  v.append(r.begin(), r.end(), cmList::ExpandElements::No);
}

#else

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

template <typename Range,
          cm::enable_if_t<cm::is_input_range<Range>::value &&
                            std::is_convertible<typename Range::value_type,
                                                cmList::value_type>::value,
                          int> = 0>
void append(cmList& v, Range const& r)
{
  v.append(r.begin(), r.end(), cmList::ExpandElements::No);
}
#endif

} // namespace cm

/**
 * Helper functions for legacy support. Use preferably cmList class directly
 * or the static methods of the class.
 */
inline void cmExpandList(
  cm::string_view arg, std::vector<std::string>& argsOut,
  cmList::EmptyElements emptyElements = cmList::EmptyElements::No)
{
  cmList::append(argsOut, arg, emptyElements);
}
inline void cmExpandList(
  cmValue arg, std::vector<std::string>& argsOut,
  cmList::EmptyElements emptyElements = cmList::EmptyElements::No)
{
  cmList::append(argsOut, arg, emptyElements);
}
