/* 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 <cstdint>
#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::intptr_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);
}
