libc++: First cut at <dynarray>

Richard Smith richard at metafoo.co.uk
Mon Sep 9 15:57:30 PDT 2013


On Mon, Sep 9, 2013 at 3:32 PM, Marshall Clow <mclow.lists at gmail.com> wrote:

> On Sep 9, 2013, at 11:59 AM, Richard Smith <richard at metafoo.co.uk> wrote:
>
> On Mon, Sep 9, 2013 at 9:06 AM, Marshall Clow <mclow.lists at gmail.com>
>  wrote:
>
>> <dynarray> See
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3662.html
>>
>> Open Issues:
>> 1) This includes <tuple> because that's where __uses_alloc_ctor lives.
>> I'm thinking that __uses_alloc_ctor should be hoisted into a common header.
>> Maybe __functional_base.
>>
>> 2) This includes a general implementation of user-allocator construction
>> (named __user_alloc_construct). This should probably be hoisted as well;
>> and possibly the code in scoped_allocator can be reworked to use it (if it
>> simplifies things).
>>
>> 3) There's no support for stack allocations at present; that requires
>> compiler support. I'm working with some people on getting that into clang.
>>
>> 4) There's an awful lot of duplication in the (many, many) constructors.
>>
>
> It's not obvious to me that the behavior of max_size is correct.
>
>
> What do you suggest it return?
> It returns the current size of the array - and that's the max size that
> array can be.
> [ This is the same behavior as std::array, btw ]
>

It's not obvious to me =)

The choices seem to either be that max_size() returns size() (the largest
size for that *instance*), or that it returns the largest size that will
not throw std::bad_array_length (the largest size for that *type*). It
seems somewhat pointless to me to even have such a member, though. What's
it for? (What generic code that operates on containers would care?)

For std::array, the case seems much clearer-cut, since the largest size for
an instance is the same as the largest size for the type.

Here's the closest I've been able to find to a use case:

bool destructive_resize_dynarray(std::dynarray<int> &arr, size_type n) {
  if (n >= arr.max_size()) return false;

  arr.~dyn_array<int>();
  new (&arr) std::dynarray<int>;
  return true;
}

> To my reading, __allocate is required to throw std::bad_array_length if
> the multiplication overflows.
>
>
> Yes. Nice catch.
> This led me down a bit of a rathole, b/c libc++ hasn't implemented
> std::bad_array_length yet.
> I'll have a (separate) patch for that up in a bit.
>
> Your reinterpret_casts from void* to (const) _Tp* could be static_casts.
>
>
> Fixed.
>
> The constructor overloads look... horribly broken. This won't work:
>
>   std::dynarray<long> arr(20, 0);
>
> ... because it picks the (size_t, const _Alloc&) constructor, not the
> (size_t, const value_type&) constructor. Is there an LWG issue for that?
>
>
> No, actually, it picks the right version; but I've added that exact case
> to the test suite.
>

It picks this constructor: dynarray(size_t, const _Alloc&), with
_Alloc=int, which is a better match than the intended dynarray(size_t,
const long&). This:

int main() {
  std::dynarray<long> dl(20, 3);
  return dl[0];
}

returns 0, not 3. (The "allocator" argument 3 is *silently ignored* because
'long' doesn't have an allocator-taking constructor.)


> I wouldn't mind some SFINAE here for the "Allocator" routines, though.
> I need a good "is_allocator" template metafunction.
>
> Thanks for the review.
>
> -- Marshall
>
> Marshall Clow     Idio Software   <mailto:mclow.lists at gmail.com<mclow.lists at gmail.com>
> >
>
> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is
> promptly moderated down to (-1, Flamebait).
>         -- Yu Suzuki
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130909/77563de0/attachment.html>


More information about the cfe-commits mailing list