@ -78,6 +78,8 @@ constexpr static auto kFixedArrayUseDefault = static_cast<size_t>(-1);
// operators.
// operators.
template < typename T , size_t inlined = kFixedArrayUseDefault >
template < typename T , size_t inlined = kFixedArrayUseDefault >
class FixedArray {
class FixedArray {
static_assert ( ! std : : is_array < T > : : value | | std : : extent < T > : : value > 0 ,
" Arrays with unknown bounds cannot be used with FixedArray. " ) ;
static constexpr size_t kInlineBytesDefault = 256 ;
static constexpr size_t kInlineBytesDefault = 256 ;
// std::iterator_traits isn't guaranteed to be SFINAE-friendly until C++17,
// std::iterator_traits isn't guaranteed to be SFINAE-friendly until C++17,
@ -337,11 +339,12 @@ class FixedArray {
}
}
private :
private :
// HolderTraits
// Holder
//
//
// Wrapper to hold elements of type T for the case where T is an array type.
// Wrapper for holding elements of type T for both the case where T is a
// If 'T' is an array type, HolderTraits::type is a struct with a 'T v;'.
// C-style array type and the general case where it is not. This is needed for
// Otherwise, HolderTraits::type is simply 'T'.
// construction and destruction of the entire array regardless of how many
// dimensions it has.
//
//
// Maintainer's Note: The simpler solution would be to simply wrap T in a
// Maintainer's Note: The simpler solution would be to simply wrap T in a
// struct whether it's an array or not: 'struct Holder { T v; };', but
// struct whether it's an array or not: 'struct Holder { T v; };', but
@ -356,35 +359,23 @@ class FixedArray {
// error: call to int __builtin___sprintf_chk(etc...)
// error: call to int __builtin___sprintf_chk(etc...)
// will always overflow destination buffer [-Werror]
// will always overflow destination buffer [-Werror]
//
//
class HolderTraits {
template < typename OuterT = value_type ,
template < typename U >
typename InnerT = absl : : remove_extent_t < OuterT > ,
struct SelectImpl {
size_t InnerN = std : : extent < OuterT > : : value >
using type = U ;
struct ArrayHolder {
static pointer AsValue ( type * p ) { return p ; }
InnerT array [ InnerN ] ;
} ;
} ;
// Partial specialization for elements of array type.
template < typename U , size_t N >
struct SelectImpl < U [ N ] > {
struct Holder { U v [ N ] ; } ;
using type = Holder ;
static pointer AsValue ( type * p ) { return & p - > v ; }
} ;
using Impl = SelectImpl < value_type > ;
public :
using Holder = absl : : conditional_t < std : : is_array < value_type > : : value ,
using type = typename Impl : : type ;
ArrayHolder < value_type > , value_type > ;
static pointer AsValue ( type * p ) { return Impl : : AsValue ( p ) ; }
static_assert ( sizeof ( Holder ) = = sizeof ( value_type ) , " " ) ;
static_assert ( alignof ( Holder ) = = alignof ( value_type ) , " " ) ;
// TODO(billydonahue): fix the type aliasing violation
static pointer AsValue ( pointer ptr ) { return ptr ; }
// this assertion hints at.
static pointer AsValue ( ArrayHolder < value_type > * ptr ) {
static_assert ( sizeof ( type ) = = sizeof ( value_type ) ,
return std : : addressof ( ptr - > array ) ;
" Holder must be same size as value_type " ) ;
}
} ;
using Holder = typename HolderTraits : : type ;
static pointer AsValue ( Holder * p ) { return HolderTraits : : AsValue ( p ) ; }
// InlineSpace
// InlineSpace
//
//