<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - std::vector incorrectly requires CopyConstructible, Destructible and other concepts"
   href="https://llvm.org/bugs/show_bug.cgi?id=28412">28412</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>std::vector incorrectly requires CopyConstructible, Destructible and other concepts
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>zilla@kayari.org
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Container requirements are all stated in terms of CopyInsertable into X, and
Erasable from X, which involves indirection through the container's allocator.

The following test shows a class which can only be constructed/destroyed by its
allocator, revealing that std::vector tries to construct temporaries directly
without going through the allocator.

/usr/local/libcxx-head/include/c++/v1/vector:1815:24: error: call to deleted
constructor of 'value_type' (aka 'X')

#include <vector>

struct Tag { };

template<typename T>
  class TaggingAllocator
  {
  public:
    using value_type = T;

    TaggingAllocator() = default;

    template<typename U>
      TaggingAllocator(const TaggingAllocator<U>&) { }

    T*
    allocate(std::size_t n) { return std::allocator<T>{}.allocate(n); }

    void
    deallocate(T* p, std::size_t n) { std::allocator<T>{}.deallocate(p, n); }

    template<typename U, typename... Args>
      void
      construct(U* p, Args&&... args)
      { ::new((void*)p) U(Tag{}, std::forward<Args>(args)...); }

    template<typename U, typename... Args>
      void
      destroy(U* p)
      { p->~U(); }
  };

template<typename T, typename U>
  bool
  operator==(const TaggingAllocator<T>&, const TaggingAllocator<U>&)
  { return true; }

template<typename T, typename U>
  bool
  operator!=(const TaggingAllocator<T>&, const TaggingAllocator<U>&)
  { return false; }

struct X
{
  // All constructors must be passed the Tag type.

  // DefaultInsertable into vector<X, TaggingAllocator<X>>,
  X(Tag) { }
  // CopyInsertable into vector<X, TaggingAllocator<X>>,
  X(Tag, const X&) { }
  // MoveInsertable into vector<X, TaggingAllocator<X>>, and
  X(Tag, X&&) { }

  // EmplaceConstructible into vector<X, TaggingAllocator<X>> from args.
  template<typename... Args>
    X(Tag, Args&&...) { }

  // not DefaultConstructible, CopyConstructible or MoveConstructible.
  X() = delete;
  X(const X&) = delete;
  X(X&&) = delete;

  // CopyAssignable.
  X& operator=(const X&) { return *this; }

  // MoveAssignable.
  X& operator=(X&&) { return *this; }

private:
  // Not Destructible.
  ~X() { }

  // Erasable from vector<X, TaggingAllocator<X>>.
  friend class TaggingAllocator<X>;
};

int main()
{
  std::vector<X, TaggingAllocator<X>> v;
  v.reserve(3);
  v.emplace_back();
  v.emplace(v.begin());
  v.emplace(v.begin(), 1, 2, 3);
}

// template class std::vector<X, TaggingAllocator<X>>;

Uncommenting the last line to explicitly instantiate the vector fails
differently, presumably there are some SFINAE conditions which make invalid
assumptions about the type.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>