Add check that d_array<E> is not unsigned int or unsigned long

`std::size_t` is `unsigned int` on i686-pc-linux-gnu, but is `unsigned
long` on x86_64-pc-linux-gnu.  This mismatch allows d_array<E =
std::size_t> to be well-formed on x86_64, but trigger a duplicate
definition of operator[](E) on i686.  Add a requires() check that
forbids both types for E, so that code which would break the i686 build
is also diagnosed in the x86_64 build.
This commit is contained in:
Kp 2022-10-09 23:15:20 +00:00
parent f61db8ae7a
commit fcb6beb3e8
3 changed files with 19 additions and 5 deletions

View file

@ -60,11 +60,21 @@ class valptridx :
template <typename>
class guarded;
class array_base_count_type;
using array_base_storage_type = typename std::conditional<
std::is_enum<typename specialized_types::integral_type>::value,
dcx::enumerated_array<managed_type, array_size, typename specialized_types::integral_type>,
std::array<managed_type, array_size>
>::type;
struct array_base_storage_integral
{
using type = std::array<managed_type, array_size>;
};
/* Note: integral_type must be an `enum` type, but
* `requires(std::is_enum<integral_type>::value)` cannot be checked
* here, because the name `array_base_storage_enum<integral_type>` may be
* formed for non-enum types, but the internal type `type` will not be
* used in those cases.
*/
template <typename integral_type>
struct array_base_storage_enum
{
using type = dcx::enumerated_array<managed_type, array_size, integral_type>;
};
protected:
using const_pointer_type = const managed_type *;
using const_reference_type = const managed_type &;
@ -75,6 +85,7 @@ protected:
*/
using typename specialized_types::integral_type;
using index_type = integral_type; // deprecated; should be dedicated UDT
using array_base_storage_type = typename std::conditional<std::is_integral<integral_type>::value, array_base_storage_integral, array_base_storage_enum<integral_type>>::type::type;
public:
class array_managed_type;

View file

@ -24,6 +24,7 @@ namespace dcx {
* Other types for E are not likely to be useful, but are not blocked.
*/
template <typename T, std::size_t N, typename E>
requires(!std::is_same<unsigned, E>::value && !std::is_same<unsigned long, E>::value)
struct enumerated_array : std::array<T, N>
{
using base_type = std::array<T, N>;

View file

@ -7,10 +7,12 @@
#pragma once
#include <cstddef>
#include <type_traits>
namespace dcx {
template <typename T, std::size_t N, typename E>
requires(!std::is_same<unsigned, E>::value && !std::is_same<unsigned long, E>::value)
struct enumerated_array;
}