ISO/ IEC JTC1/SC22/WG21 N1620

                                                        N1620=04-0060
                                                        Howard Hinnant
                                                        24 Mar 2004

                          Dimension and Rank

Resolution to TR issue 3.9


4.2  Header <type_traits> synopsis:

Add under:

// type properties:
...
template <class T> struct rank;
template <class T, unsigned I = 0> struct extent;

Change:

template <class T> struct remove_dimension;
template <class T> struct remove_all_dimensions;

to:

template <class T> struct remove_extent;
template <class T> struct remove_all_extents;

4.3.4 Type properties

Add:

template <class T> struct rank {
 static const std::size_t value = implementation_defined;
  typedef std::size_t                        value_type;
 typedef integral_constant<value_type,value> type;
 operator type()const;
};

value: An implementation-defined integer value representing the rank
of objects of type T (8.3.4). [Note - the term "rank" here is used to
describe the number of dimensions of an array type - end note]

[example -

 // the following assertions should hold:
assert(rank<int>::value == 0);
assert(rank<int[2]>::value == 1);
assert(rank<int[][4]>::value == 2);

- end example]

...

template <class T, unsigned I = 0> struct extent {
 static const std::size_t value = implementation_defined;
  typedef std::size_t value_type;
 typedef integral_constant<value_type,value> type;
 operator type()const;
};

value: An implementation-defined integer value representing the extent
(dimension) of the I'th bound of objects of type T (8.3.4). If the
type T is not an array type, has rank of less than I, or if I == 0 and
is of type "array of unknown bound of T", then value shall evaluate to
zero; otherwise value shall evaluate to the number of elements in the
I'th array bound of T. [Note - the term "extent" here is used to
describe the number of elements in an array type - end note]

[example -

 // the following assertions should hold:
assert(extent<int>::value == 0);
assert(extent<int[2]>::value == 2);
assert(extent<int[2][4]>::value == 2);
assert(extent<int[][4]>::value == 0);
assert((extent<int, 1>::value) == 0);
assert((extent<int[2], 1>::value) == 0);
assert((extent<int[2][4], 1>::value) == 4);
assert((extent<int[][4], 1>::value) == 4);

- end example]

4.5.3 Array modifications:

Change:

template <class T> struct remove_dimension{
   typedef T type;
};
template <class T, std::size_t N> struct remove_dimension<T[N]>{
   typedef T type;
};
template <class T> struct remove_dimension<T[]>{
   typedefs T type;
};

to:

template <class T> struct remove_extent {
   typedef T type;
};
template <class T, std::size_t N> struct remove_extent<T[N]> {
   typedef T type;
};
template <class T> struct remove_extent<T[]> {
   typedef T type;
};

Change:

[example
  // the following assertions should all hold:
  assert((is_same<remove_dimension<int>::type, int>::value));
  assert((is_same<remove_dimension<int[2]>::type, int>::value));
  assert((is_same<remove_dimension<int[2][3]>::type, int[3]>::value));
  assert((is_same<remove_dimension<int[][3]>::type, int[3]>::value));
Ņend example]

template <class T> struct remove_all_dimensions {
   typedef T type;
};
template <class T, std::size_t N> struct remove_all_dimensions<T[N]> {
   typedef typename remove_all_dimensions<T>::type type;
};
template <class T> struct remove_all_dimensions<T[]> {
   typedef typename remove_all_dimensions<T>::type type;
};

to:

[example
  // the following assertions should all hold:
  assert((is_same<remove_extent<int>::type, int>::value));
  assert((is_same<remove_extent<int[2]>::type, int>::value));
  assert((is_same<remove_extent<int[2][3]>::type, int[3]>::value));
  assert((is_same<remove_extent<int[][3]>::type, int[3]>::value));
Ņend example]

template <class T> struct remove_all_extents {
   typedef T type;
};
template <class T, std::size_t N> struct remove_all_extents<T[N]> {
   typedef typename remove_all_extents<T>::type type;
};
template <class T> struct remove_all_extents<T[]> {
   typedef typename remove_all_extents<T>::type type;
};

Change:

[example
  // the following assertions should all hold:
  assert((is_same<remove_all_dimensions<int>::type, int>::value));
  assert((is_same<remove_all_dimensions<int[2]>::type, int>::value));
  assert((is_same<remove_all_dimensions<int[2][3]>::type, int>::value));
  assert((is_same<remove_all_dimensions<int[][3]>::type, int>::value));
Ņend example]

to:

[example
  // the following assertions should all hold:
  assert((is_same<remove_all_extents<int>::type, int>::value));
  assert((is_same<remove_all_extents<int[2]>::type, int>::value));
  assert((is_same<remove_all_extents<int[2][3]>::type, int>::value));
  assert((is_same<remove_all_extents<int[][3]>::type, int>::value));
Ņend example]

4.5.4 Pointer modifications

Change:

template <class T> struct add_pointer {
   typedef typename remove_dimension<
      typename remove_reference<T>::type
               >::type*
           type;
};

to:

template <class T> struct add_pointer
{
   typedef typename remove_extent
   <
      typename remove_reference<T>::type
   >::type* type;
};

4.6 Implementation requirements

Change:

is_pod<T>::value == is_pod<remove_dimension<T>::type>::value

to:

is_pod<T>::value == is_pod<remove_extent<T>::type>::value

Change:

has_trivial_*<T>::value == has_trivial_*<remove_dimension<T>::type>::value

to:

has_trivial_*<T>::value == has_trivial_*<remove_extent<T>::type>::value