// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This is a "No Compile Test" suite. // http://dev.chromium.org/developers/testing/no-compile-tests #include #include "base/optional.h" namespace base { #if defined(NCTEST_EXPLICIT_CONVERTING_COPY_CONSTRUCTOR) // [r"fatal error: no matching function for call to object of type"] // Optional(const Optional& arg) constructor is marked explicit if // T is not convertible from "const U&". void WontCompile() { struct Test { // Declares as explicit so that Test is still constructible from int, // but not convertible. explicit Test(int a) {} }; static_assert(!std::is_convertible::value, "const int& to Test is convertible"); const Optional arg(in_place, 1); ([](Optional param) {})(arg); } #elif defined(NCTEST_EXPLICIT_CONVERTING_MOVE_CONSTRUCTOR) // [r"fatal error: no matching function for call to object of type"] // Optional(Optional&& arg) constructor is marked explicit if // T is not convertible from "U&&". void WontCompile() { struct Test { // Declares as explicit so that Test is still constructible from int, // but not convertible. explicit Test(int a) {} }; static_assert(!std::is_convertible::value, "int&& to Test is convertible"); ([](Optional param) {})(Optional(in_place, 1)); } #elif defined(NCTEST_EXPLICIT_VALUE_FORWARD_CONSTRUCTOR) // [r"fatal error: no matching function for call to object of type"] // Optional(U&&) constructor is marked explicit if T is not convertible // from U&&. void WontCompile() { struct Test { // Declares as explicit so that Test is still constructible from int, // but not convertible. explicit Test(int a) {} }; static_assert(!std::is_convertible::value, "int&& to Test is convertible"); ([](Optional param) {})(1); } #elif defined(NCTEST_ILL_FORMED_IN_PLACET_T) // [r"instantiation of base::Optional with in_place_t is ill-formed"] // Optional is ill-formed if T is `in_place_t`. void WontCompile() { Optional optional; optional.has_value(); } #elif defined(NCTEST_ILL_FORMED_CONST_IN_PLACET_T) // [r"instantiation of base::Optional with in_place_t is ill-formed"] // Optional is ill-formed if T is `const in_place_t`. void WontCompile() { Optional optional; optional.has_value(); } #elif defined(NCTEST_ILL_FORMED_NULLOPT_T) // [r"instantiation of base::Optional with nullopt_t is ill-formed"] // Optional is ill-formed if T is `const nullopt_t`. void WontCompile() { Optional optional; optional.has_value(); } #elif defined(NCTEST_ILL_FORMED_CONST_NULLOPT_T) // [r"instantiation of base::Optional with nullopt_t is ill-formed"] // Optional is ill-formed if T is `const nullopt_t`. void WontCompile() { Optional optional; optional.has_value(); } #elif defined(NCTEST_ILL_FORMED_NON_DESTRUCTIBLE) // [r"instantiation of base::Optional with a non-destructible type is ill-formed"] // Optional is ill-formed if T is non-destructible. void WontCompile() { struct T { private: ~T(); }; static_assert(!std::is_destructible::value, "T is not destructible"); Optional optional; optional.has_value(); } // TODO(crbug.com/967722): the error message should be about the instantiation of an // ill-formed base::Optional. #elif defined(NCTEST_ILL_FORMED_REFERENCE) // [r"fatal error: union member 'value_' has reference type 'int &'"] // Optional is ill-formed if T is a reference. void WontCompile() { using T = int&; static_assert(std::is_reference::value, "T is a reference"); Optional optional; optional.has_value(); } // TODO(crbug.com/967722): the error message should be about the instantiation of an // ill-formed base::Optional. #elif defined(NCTEST_ILL_FORMED_CONST_REFERENCE) // [r"fatal error: union member 'value_' has reference type 'const int &'"] // Optional is ill-formed if T is a const reference. void WontCompile() { using T = const int&; static_assert(std::is_reference::value, "T is a reference"); Optional optional; optional.has_value(); } #elif defined(NCTEST_ILL_FORMED_FIXED_LENGTH_ARRAY) // [r"instantiation of base::Optional with an array type is ill-formed"] // Optional is ill-formed if T is a fixed length array. void WontCompile() { using T = char[4]; static_assert(std::is_array::value, "T is an array"); Optional optional; optional.has_value(); } // TODO(crbug.com/967722): the error message should be about the instantiation of an // ill-formed base::Optional. #elif defined(NCTEST_ILL_FORMED_UNDEFINED_LENGTH_ARRAY) // [r"fatal error: base class 'OptionalStorageBase' has a flexible array member"] // Optional is ill-formed if T is a undefined length array. void WontCompile() { using T = char[]; static_assert(std::is_array::value, "T is an array"); Optional optional; optional.has_value(); } #endif } // namespace base