From 633010a3a0b8542860032573f3a9e86f6c20d53e Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Wed, 23 Mar 2022 11:47:19 +0000 Subject: [PATCH] Replace nonstd::optional by C++17 std::optional Removes third-party code that is no longer necessary now that we use C++ 17 as build standard. Future uses of optionalt should instead use std::optional directly. --- CODEOWNERS | 1 - doc/architectural/folder-walkthrough.md | 3 - jbmc/src/java_bytecode/ci_lazy_methods.h | 2 +- .../dynamic-frames/dfcc_cfg_info.cpp | 4 +- .../dfcc_lift_memory_predicates.cpp | 2 +- src/goto-programs/link_goto_model.cpp | 2 +- src/nonstd/README.md | 7 - src/nonstd/module_dependencies.txt | 1 - src/nonstd/optional.hpp | 1089 ----------------- src/solvers/flattening/boolbv_overflow.cpp | 2 +- src/solvers/flattening/boolbv_width.h | 2 +- src/solvers/strings/string_dependencies.h | 3 +- src/util/arith_tools.h | 6 +- src/util/module_dependencies.txt | 1 - src/util/numbering.h | 2 +- src/util/optional.h | 55 +- src/util/sharing_map.h | 2 +- src/util/string2int.h | 4 +- unit/Makefile | 1 - unit/util/optional.cpp | 32 - 20 files changed, 27 insertions(+), 1194 deletions(-) delete mode 100644 src/nonstd/README.md delete mode 100644 src/nonstd/module_dependencies.txt delete mode 100644 src/nonstd/optional.hpp delete mode 100644 unit/util/optional.cpp diff --git a/CODEOWNERS b/CODEOWNERS index 1b456784481..8fc1e16f58f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -23,7 +23,6 @@ /src/json-symtab-language/ @martin-cs /src/langapi/ @kroening @tautschnig @peterschrammel /src/xmllang/ @kroening @tautschnig @peterschrammel -/src/nonstd/ @peterschrammel /src/solvers/flattening @martin-cs @kroening @tautschnig @peterschrammel /src/solvers/floatbv @martin-cs @kroening /src/solvers/miniBDD @tautschnig @kroening diff --git a/doc/architectural/folder-walkthrough.md b/doc/architectural/folder-walkthrough.md index 53b69641bf9..5d5643d804c 100644 --- a/doc/architectural/folder-walkthrough.md +++ b/doc/architectural/folder-walkthrough.md @@ -51,7 +51,6 @@ containing the code for a different part of the system. * \ref xmllang * \ref util * \ref miniz - * \ref nonstd In the top level of `src` there are only a few files: @@ -167,7 +166,6 @@ digraph directory_dependencies { big_int [label = "big-int", URL = "\ref big-int"]; miniz [URL = "\ref miniz"]; util [URL = "\ref util"]; - nonstd [URL = "\ref nonstd"]; json [URL = "\ref json"]; xmllang [URL = "\ref xmllang"]; assembler [URL = "\ref assembler"]; @@ -203,6 +201,5 @@ digraph directory_dependencies { xmllang -> util; assembler -> util; util -> big_int; - util -> nonstd; } \enddot diff --git a/jbmc/src/java_bytecode/ci_lazy_methods.h b/jbmc/src/java_bytecode/ci_lazy_methods.h index 04fab8e5068..d96174aec39 100644 --- a/jbmc/src/java_bytecode/ci_lazy_methods.h +++ b/jbmc/src/java_bytecode/ci_lazy_methods.h @@ -82,7 +82,7 @@ class method_bytecodet { const auto it = map.find(method_id); if(it == map.end()) - return opt_reft(); + return std::nullopt; return std::cref(it->second); } }; diff --git a/src/goto-instrument/contracts/dynamic-frames/dfcc_cfg_info.cpp b/src/goto-instrument/contracts/dynamic-frames/dfcc_cfg_info.cpp index 25142e28307..7eb14538971 100644 --- a/src/goto-instrument/contracts/dynamic-frames/dfcc_cfg_info.cpp +++ b/src/goto-instrument/contracts/dynamic-frames/dfcc_cfg_info.cpp @@ -138,7 +138,7 @@ dfcc_loop_infot::find_head(goto_programt &goto_program) const optionalt dfcc_loop_infot::find_latch(goto_programt &goto_program) const { - optionalt result = nullopt; + optionalt result = std::nullopt; for(auto target = goto_program.instructions.begin(); target != goto_program.instructions.end(); target++) @@ -728,7 +728,7 @@ dfcc_cfg_infot::get_outer_loop_identifier(const std::size_t loop_id) const } } // return nullopt for loops that are not nested in other loops - return nullopt; + return std::nullopt; } bool dfcc_cfg_infot::is_valid_loop_or_top_level_id(const std::size_t id) const diff --git a/src/goto-instrument/contracts/dynamic-frames/dfcc_lift_memory_predicates.cpp b/src/goto-instrument/contracts/dynamic-frames/dfcc_lift_memory_predicates.cpp index 47953afeda8..3669ab3c183 100644 --- a/src/goto-instrument/contracts/dynamic-frames/dfcc_lift_memory_predicates.cpp +++ b/src/goto-instrument/contracts/dynamic-frames/dfcc_lift_memory_predicates.cpp @@ -331,7 +331,7 @@ void dfcc_lift_memory_predicatest::lift_parameters_and_update_body( // rewrite all occurrences of lifted parameters instruction.transform([&replace_lifted_params](exprt expr) { const bool changed = !replace_lifted_params.replace(expr); - return changed ? optionalt{expr} : nullopt; + return changed ? optionalt{expr} : std::nullopt; }); // add address-of to all arguments expressions passed in lifted position to diff --git a/src/goto-programs/link_goto_model.cpp b/src/goto-programs/link_goto_model.cpp index 9d8343977b8..5c66ae0d6ef 100644 --- a/src/goto-programs/link_goto_model.cpp +++ b/src/goto-programs/link_goto_model.cpp @@ -217,7 +217,7 @@ void finalize_linking( { instruction.transform([&object_type_updates](exprt expr) { const bool changed = !object_type_updates.replace(expr); - return changed ? optionalt{expr} : nullopt; + return changed ? optionalt{expr} : std::nullopt; }); } } diff --git a/src/nonstd/README.md b/src/nonstd/README.md deleted file mode 100644 index aebbaabb6ff..00000000000 --- a/src/nonstd/README.md +++ /dev/null @@ -1,7 +0,0 @@ -\ingroup module_hidden -\defgroup nonstd nonstd - -# Folder nonstd - -`nonstd` contains implementations of C++ utilities that are not yet -part of the standard library, e.g. for `optional`. diff --git a/src/nonstd/module_dependencies.txt b/src/nonstd/module_dependencies.txt deleted file mode 100644 index 55e484b8664..00000000000 --- a/src/nonstd/module_dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -nonstd diff --git a/src/nonstd/optional.hpp b/src/nonstd/optional.hpp deleted file mode 100644 index 60011dff73c..00000000000 --- a/src/nonstd/optional.hpp +++ /dev/null @@ -1,1089 +0,0 @@ -// -// Copyright (c) 2016 Martin Moene -// -// https://github.com/martinmoene/optional-lite -// -// This code is licensed under the MIT License (MIT). -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -// IWYU pragma: private, include -// IWYU pragma: private, include "optional.h" - -#pragma once - -#ifndef NONSTD_OPTIONAL_LITE_HPP -#define NONSTD_OPTIONAL_LITE_HPP - -#include -#include -#include - -#define optional_lite_VERSION "2.1.0" - -// variant-lite alignment configuration: - -#ifndef optional_CONFIG_MAX_ALIGN_HACK -# define optional_CONFIG_MAX_ALIGN_HACK 0 -#endif - -#ifndef optional_CONFIG_ALIGN_AS -// no default, used in #if defined() -#endif - -#ifndef optional_CONFIG_ALIGN_AS_FALLBACK -# define optional_CONFIG_ALIGN_AS_FALLBACK double -#endif - -// Compiler detection (C++17 is speculative): - -#define optional_CPP11_OR_GREATER ( __cplusplus >= 201103L ) -#define optional_CPP14_OR_GREATER ( __cplusplus >= 201402L ) -#define optional_CPP17_OR_GREATER ( __cplusplus >= 201700L ) - -// half-open range [lo..hi): -#define optional_BETWEEN( v, lo, hi ) ( lo <= v && v < hi ) - -#if defined(_MSC_VER) && !defined(__clang__) -# define optional_COMPILER_MSVC_VERSION (_MSC_VER / 100 - 5 - (_MSC_VER < 1900)) -#else -# define optional_COMPILER_MSVC_VERSION 0 -#endif - -#if defined __GNUC__ -# define optional_COMPILER_GNUC_VERSION __GNUC__ -#else -# define optional_COMPILER_GNUC_VERSION 0 -#endif - -#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 7, 14 ) -# pragma warning( push ) -# pragma warning( disable: 4345 ) // initialization behavior changed -#endif - -#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 7, 15 ) -# pragma warning( push ) -# pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const' -#endif - -// Presence of C++11 language features: - -#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 10 -# define optional_HAVE_AUTO 1 -# define optional_HAVE_NULLPTR 1 -# define optional_HAVE_STATIC_ASSERT 1 -#endif - -#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 12 -# define optional_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1 -# define optional_HAVE_INITIALIZER_LIST 1 -#endif - -#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 14 -# define optional_HAVE_ALIAS_TEMPLATE 1 -# define optional_HAVE_CONSTEXPR_11 1 -# define optional_HAVE_ENUM_CLASS 1 -# define optional_HAVE_EXPLICIT_CONVERSION 1 -# define optional_HAVE_IS_DEFAULT 1 -# define optional_HAVE_IS_DELETE 1 -# define optional_HAVE_NOEXCEPT 1 -# define optional_HAVE_REF_QUALIFIER 1 -#endif - -// Presence of C++14 language features: - -#if optional_CPP14_OR_GREATER -# define optional_HAVE_CONSTEXPR_14 1 -#endif - -// Presence of C++17 language features: - -#if optional_CPP17_OR_GREATER -# define optional_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE 1 -#endif - -// Presence of C++ library features: - -#if optional_COMPILER_GNUC_VERSION -# define optional_HAVE_TR1_TYPE_TRAITS 1 -# define optional_HAVE_TR1_ADD_POINTER 1 -#endif - -#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 9 -# define optional_HAVE_TYPE_TRAITS 1 -# define optional_HAVE_STD_ADD_POINTER 1 -#endif - -#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 11 -# define optional_HAVE_ARRAY 1 -#endif - -#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 12 -# define optional_HAVE_CONDITIONAL 1 -#endif - -#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 14 || (optional_COMPILER_MSVC_VERSION >= 9 && _HAS_CPP0X) -# define optional_HAVE_CONTAINER_DATA_METHOD 1 -#endif - -#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 12 -# define optional_HAVE_REMOVE_CV 1 -#endif - -#if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 14 -# define optional_HAVE_SIZED_TYPES 1 -#endif - -// For the rest, consider VC14 as C++11 for variant-lite: - -#if optional_COMPILER_MSVC_VERSION >= 14 -# undef optional_CPP11_OR_GREATER -# define optional_CPP11_OR_GREATER 1 -#endif - -// C++ feature usage: - -#if optional_HAVE_CONSTEXPR_11 -# define optional_constexpr constexpr -#else -# define optional_constexpr /*constexpr*/ -#endif - -#if optional_HAVE_CONSTEXPR_14 -# define optional_constexpr14 constexpr -#else -# define optional_constexpr14 /*constexpr*/ -#endif - -#if optional_HAVE_NOEXCEPT -# define optional_noexcept noexcept -#else -# define optional_noexcept /*noexcept*/ -#endif - -#if optional_HAVE_NULLPTR -# define optional_nullptr nullptr -#else -# define optional_nullptr NULL -#endif - -#if optional_HAVE_REF_QUALIFIER -# define optional_ref_qual & -# define optional_refref_qual && -#else -# define optional_ref_qual /*&*/ -# define optional_refref_qual /*&&*/ -#endif - -// additional includes: - -#if optional_CPP11_OR_GREATER -# include -#endif - -#if optional_HAVE_INITIALIZER_LIST -# include -#endif - -#if optional_HAVE_TYPE_TRAITS -# include -#elif optional_HAVE_TR1_TYPE_TRAITS -# include -#endif - -// -// in_place: code duplicated in any-lite, optional-lite, variant-lite: -// - -#if ! nonstd_lite_HAVE_IN_PLACE_TYPES - -namespace nonstd { - -namespace detail { - -template< class T > -struct in_place_type_tag {}; - -template< std::size_t I > -struct in_place_index_tag {}; - -} // namespace detail - -struct in_place_t {}; - -template< class T > -inline in_place_t in_place( detail::in_place_type_tag = detail::in_place_type_tag() ) -{ - return in_place_t(); -} - -template< std::size_t I > -inline in_place_t in_place( detail::in_place_index_tag = detail::in_place_index_tag() ) -{ - return in_place_t(); -} - -// mimic templated typedef: - -#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) -#define nonstd_lite_in_place_index_t(T) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag ) - -#define nonstd_lite_HAVE_IN_PLACE_TYPES 1 - -} // namespace nonstd - -#endif // nonstd_lite_HAVE_IN_PLACE_TYPES - -// -// optional: -// - -namespace nonstd { namespace optional_lite { - -/// class optional - -template< typename T > -class optional; - -namespace detail { - -// C++11 emulation: - -#if variant_HAVE_CONDITIONAL - -using std::conditional; - -#else - -template< bool Cond, class Then, class Else > -struct conditional; - -template< class Then, class Else > -struct conditional< true , Then, Else > { typedef Then type; }; - -template< class Then, class Else > -struct conditional< false, Then, Else > { typedef Else type; }; - -#endif // variant_HAVE_CONDITIONAL - -struct nulltype{}; - -template< typename Head, typename Tail > -struct typelist -{ - typedef Head head; - typedef Tail tail; -}; - -#if optional_CONFIG_MAX_ALIGN_HACK - -// Max align, use most restricted type for alignment: - -#define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ ) -#define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line ) -#define optional_UNIQUE3( name, line ) name ## line - -#define optional_ALIGN_TYPE( type ) \ - type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st ) - -template< typename T > -struct struct_t { T _; }; - -union max_align_t -{ - optional_ALIGN_TYPE( char ); - optional_ALIGN_TYPE( short int ); - optional_ALIGN_TYPE( int ); - optional_ALIGN_TYPE( long int ); - optional_ALIGN_TYPE( float ); - optional_ALIGN_TYPE( double ); - optional_ALIGN_TYPE( long double ); - optional_ALIGN_TYPE( char * ); - optional_ALIGN_TYPE( short int * ); - optional_ALIGN_TYPE( int * ); - optional_ALIGN_TYPE( long int * ); - optional_ALIGN_TYPE( float * ); - optional_ALIGN_TYPE( double * ); - optional_ALIGN_TYPE( long double * ); - optional_ALIGN_TYPE( void * ); - -#ifdef HAVE_LONG_LONG - optional_ALIGN_TYPE( long long ); -#endif - - struct Unknown; - - Unknown ( * optional_UNIQUE(_) )( Unknown ); - Unknown * Unknown::* optional_UNIQUE(_); - Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown ); - - struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_); - struct_t< Unknown * Unknown::* > optional_UNIQUE(_); - struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_); -}; - -#undef optional_UNIQUE -#undef optional_UNIQUE2 -#undef optional_UNIQUE3 - -#undef optional_ALIGN_TYPE - -#elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK - -// Use user-specified type for alignment: - -#define optional_ALIGN_AS( unused ) \ - optional_CONFIG_ALIGN_AS - -#else // optional_CONFIG_MAX_ALIGN_HACK - -// Determine POD type to use for alignment: - -#define optional_ALIGN_AS( to_align ) \ - typename type_of_size< alignment_types, alignment_of< to_align >::value >::type - -template -struct alignment_of; - -template -struct alignment_of_hack -{ - char c; - T t; - alignment_of_hack(); -}; - -template -struct alignment_logic -{ - enum { value = A < S ? A : S }; -}; - -template< typename T > -struct alignment_of -{ - enum { value = alignment_logic< - sizeof( alignment_of_hack ) - sizeof(T), sizeof(T) >::value, }; -}; - -template< typename List, size_t N > -struct type_of_size -{ - typedef typename conditional< - N == sizeof( typename List::head ), - typename List::head, - typename type_of_size::type >::type type; -}; - -template< size_t N > -struct type_of_size< nulltype, N > -{ - typedef optional_CONFIG_ALIGN_AS_FALLBACK type; -}; - -template< typename T> -struct struct_t { T _; }; - -#define optional_ALIGN_TYPE( type ) \ - typelist< type , typelist< struct_t< type > - -struct Unknown; - -typedef - optional_ALIGN_TYPE( char ), - optional_ALIGN_TYPE( short ), - optional_ALIGN_TYPE( int ), - optional_ALIGN_TYPE( long ), - optional_ALIGN_TYPE( float ), - optional_ALIGN_TYPE( double ), - optional_ALIGN_TYPE( long double ), - - optional_ALIGN_TYPE( char *), - optional_ALIGN_TYPE( short * ), - optional_ALIGN_TYPE( int * ), - optional_ALIGN_TYPE( long * ), - optional_ALIGN_TYPE( float * ), - optional_ALIGN_TYPE( double * ), - optional_ALIGN_TYPE( long double * ), - - optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ), - optional_ALIGN_TYPE( Unknown * Unknown::* ), - optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ), - - nulltype - > > > > > > > > > > > > > > - > > > > > > > > > > > > > > - > > > > > > - alignment_types; - -#undef optional_ALIGN_TYPE - -#endif // optional_CONFIG_MAX_ALIGN_HACK - -/// C++03 constructed union to hold value. - -template< typename T > -union storage_t -{ -private: - friend class optional; - - typedef T value_type; - - storage_t() {} - - storage_t( value_type const & v ) - { - construct_value( v ); - } - - void construct_value( value_type const & v ) - { - ::new( value_ptr() ) value_type( v ); - } - -#if optional_CPP11_OR_GREATER - - storage_t( value_type && v ) - { - construct_value( std::move( v ) ); - } - - void construct_value( value_type && v ) - { - ::new( value_ptr() ) value_type( std::move( v ) ); - } - -#endif - - void destruct_value() - { - value_ptr()->~T(); - } - - value_type const * value_ptr() const - { - return as(); - } - - value_type * value_ptr() - { - return as(); - } - - value_type const & value() const optional_ref_qual - { - return * value_ptr(); - } - - value_type & value() optional_ref_qual - { - return * value_ptr(); - } - -#if optional_CPP11_OR_GREATER - - value_type const && value() const optional_refref_qual - { - return * value_ptr(); - } - - value_type && value() optional_refref_qual - { - return * value_ptr(); - } - -#endif - -#if optional_CPP11_OR_GREATER - - using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type; - aligned_storage_t data; - -#elif optional_CONFIG_MAX_ALIGN_HACK - - typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t; - - max_align_t hack; - aligned_storage_t data; - -#else - typedef optional_ALIGN_AS(value_type) align_as_type; - - typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t; - aligned_storage_t data; - -#undef optional_ALIGN_AS - -#endif // optional_CONFIG_MAX_ALIGN_HACK - - void * ptr() optional_noexcept - { - return &data; - } - - void const * ptr() const optional_noexcept - { - return &data; - } - - template - U * as() - { - return reinterpret_cast( ptr() ); - } - - template - U const * as() const - { - return reinterpret_cast( ptr() ); - } -}; - -} // namespace detail - -/// disengaged state tag - -struct nullopt_t -{ - struct init{}; - optional_constexpr nullopt_t( init ) {} -}; - -#if optional_HAVE_CONSTEXPR_11 -constexpr nullopt_t nullopt{ nullopt_t::init{} }; -#else -// extra parenthesis to prevent the most vexing parse: -const nullopt_t nullopt(( nullopt_t::init() )); -#endif - -/// optional access error - -class bad_optional_access : public std::logic_error -{ -public: - explicit bad_optional_access() - : logic_error( "bad optional access" ) {} -}; - -/// optional - -template< typename T> -class optional -{ -private: - typedef void (optional::*safe_bool)() const; - -public: - typedef T value_type; - - optional_constexpr optional() optional_noexcept - : has_value_( false ) - , contained() - {} - - optional_constexpr optional( nullopt_t ) optional_noexcept - : has_value_( false ) - , contained() - {} - - optional( optional const & rhs ) - : has_value_( rhs.has_value() ) - { - if ( rhs.has_value() ) - contained.construct_value( rhs.contained.value() ); - } - -#if optional_CPP11_OR_GREATER - optional_constexpr14 optional( optional && rhs ) noexcept( std::is_nothrow_move_constructible::value ) - : has_value_( rhs.has_value() ) - { - if ( rhs.has_value() ) - contained.construct_value( std::move( rhs.contained.value() ) ); - } -#endif - - optional_constexpr optional( value_type const & value ) - : has_value_( true ) - , contained( value ) - {} - -#if optional_CPP11_OR_GREATER - - optional_constexpr optional( value_type && value ) - : has_value_( true ) - , contained( std::move( value ) ) - {} - - template< class... Args > - optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), Args&&... args ) - : has_value_( true ) - , contained( T( std::forward(args)...) ) - {} - - template< class U, class... Args > - optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), std::initializer_list il, Args&&... args ) - : has_value_( true ) - , contained( T( il, std::forward(args)...) ) - {} - -#endif // optional_CPP11_OR_GREATER - - ~optional() - { - if ( has_value() ) - contained.destruct_value(); - } - - // assignment - - optional & operator=( nullopt_t ) optional_noexcept - { - reset(); - return *this; - } - - optional & operator=( optional const & rhs ) -#if optional_CPP11_OR_GREATER - noexcept( std::is_nothrow_move_assignable::value && std::is_nothrow_move_constructible::value ) -#endif - { - if ( has_value() == true && rhs.has_value() == false ) reset(); - else if ( has_value() == false && rhs.has_value() == true ) initialize( *rhs ); - else if ( has_value() == true && rhs.has_value() == true ) contained.value() = *rhs; - return *this; - } - -#if optional_CPP11_OR_GREATER - - optional & operator=( optional && rhs ) noexcept - { - if ( has_value() == true && rhs.has_value() == false ) reset(); - else if ( has_value() == false && rhs.has_value() == true ) initialize( std::move( *rhs ) ); - else if ( has_value() == true && rhs.has_value() == true ) contained.value() = std::move( *rhs ); - return *this; - } - - template< class U, - typename = typename std::enable_if< std::is_same< typename std::decay::type, T>::value >::type > - optional & operator=( U && v ) - { - if ( has_value() ) contained.value() = std::forward( v ); - else initialize( T( std::forward( v ) ) ); - return *this; - } - - template< class... Args > - void emplace( Args&&... args ) - { - *this = nullopt; - initialize( T( std::forward(args)...) ); - } - - template< class U, class... Args > - void emplace( std::initializer_list il, Args&&... args ) - { - *this = nullopt; - initialize( T( il, std::forward(args)...) ); - } - -#endif // optional_CPP11_OR_GREATER - - // swap - - void swap( optional & rhs ) -#if optional_CPP11_OR_GREATER - noexcept( std::is_nothrow_move_constructible::value && noexcept( std::swap( std::declval(), std::declval() ) ) ) -#endif - { - using std::swap; - if ( has_value() == true && rhs.has_value() == true ) { swap( **this, *rhs ); } - else if ( has_value() == false && rhs.has_value() == true ) { initialize( *rhs ); rhs.reset(); } - else if ( has_value() == true && rhs.has_value() == false ) { rhs.initialize( **this ); reset(); } - } - - // observers - - optional_constexpr value_type const * operator ->() const - { - return assert( has_value() ), - contained.value_ptr(); - } - - optional_constexpr14 value_type * operator ->() - { - return assert( has_value() ), - contained.value_ptr(); - } - - optional_constexpr value_type const & operator *() const optional_ref_qual - { - return assert( has_value() ), - contained.value(); - } - - optional_constexpr14 value_type & operator *() optional_ref_qual - { - return assert( has_value() ), - contained.value(); - } - -#if optional_CPP11_OR_GREATER - - optional_constexpr value_type const && operator *() const optional_refref_qual - { - return assert( has_value() ), std::move( contained.value() ); - } - - optional_constexpr14 value_type && operator *() optional_refref_qual - { - assert( has_value() ); - return std::move( contained.value() ); - } - -#endif - -#if optional_CPP11_OR_GREATER - optional_constexpr explicit operator bool() const optional_noexcept - { - return has_value(); - } -#else - optional_constexpr operator safe_bool() const optional_noexcept - { - return has_value() ? &optional::this_type_does_not_support_comparisons : 0; - } -#endif - - optional_constexpr bool has_value() const optional_noexcept - { - return has_value_; - } - - optional_constexpr14 value_type const & value() const optional_ref_qual - { - if ( ! has_value() ) - throw bad_optional_access(); - - return contained.value(); - } - - optional_constexpr14 value_type & value() optional_ref_qual - { - if ( ! has_value() ) - throw bad_optional_access(); - - return contained.value(); - } - -#if optional_HAVE_REF_QUALIFIER - - optional_constexpr14 value_type const && value() const optional_refref_qual - { - if ( ! has_value() ) - throw bad_optional_access(); - - return std::move( contained.value() ); - } - - optional_constexpr14 value_type && value() optional_refref_qual - { - if ( ! has_value() ) - throw bad_optional_access(); - - return std::move( contained.value() ); - } - -#endif - -#if optional_CPP11_OR_GREATER - - template< class U > - optional_constexpr value_type value_or( U && v ) const optional_ref_qual - { - return has_value() ? contained.value() : static_cast(std::forward( v ) ); - } - - template< class U > - optional_constexpr value_type value_or( U && v ) const optional_refref_qual - { - return has_value() ? std::move( contained.value() ) : static_cast(std::forward( v ) ); - } - -#else - - template< class U > - optional_constexpr value_type value_or( U const & v ) const - { - return has_value() ? contained.value() : static_cast( v ); - } - -#endif // optional_CPP11_OR_GREATER - - // modifiers - - void reset() optional_noexcept - { - if ( has_value() ) - contained.destruct_value(); - - has_value_ = false; - } - -private: - void this_type_does_not_support_comparisons() const {} - - template< typename V > - void initialize( V const & value ) - { - assert( ! has_value() ); - contained.construct_value( value ); - has_value_ = true; - } - -#if optional_CPP11_OR_GREATER - template< typename V > - void initialize( V && value ) - { - assert( ! has_value() ); - contained.construct_value( std::move( value ) ); - has_value_ = true; - } -#endif - -private: - bool has_value_; - detail::storage_t< value_type > contained; - -}; - -// Relational operators - -template< typename T > bool operator==( optional const & x, optional const & y ) -{ - return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y; -} - -template< typename T > bool operator!=( optional const & x, optional const & y ) -{ - return !(x == y); -} - -template< typename T > bool operator<( optional const & x, optional const & y ) -{ - return (!y) ? false : (!x) ? true : *x < *y; -} - -template< typename T > bool operator>( optional const & x, optional const & y ) -{ - return (y < x); -} - -template< typename T > bool operator<=( optional const & x, optional const & y ) -{ - return !(y < x); -} - -template< typename T > bool operator>=( optional const & x, optional const & y ) -{ - return !(x < y); -} - -// Comparison with nullopt - -template< typename T > bool operator==( optional const & x, nullopt_t ) optional_noexcept -{ - return (!x); -} - -template< typename T > bool operator==( nullopt_t, optional const & x ) optional_noexcept -{ - return (!x); -} - -template< typename T > bool operator!=( optional const & x, nullopt_t ) optional_noexcept -{ - return bool(x); -} - -template< typename T > bool operator!=( nullopt_t, optional const & x ) optional_noexcept -{ - return bool(x); -} - -template< typename T > bool operator<( optional const &, nullopt_t ) optional_noexcept -{ - return false; -} - -template< typename T > bool operator<( nullopt_t, optional const & x ) optional_noexcept -{ - return bool(x); -} - -template< typename T > bool operator<=( optional const & x, nullopt_t ) optional_noexcept -{ - return (!x); -} - -template< typename T > bool operator<=( nullopt_t, optional const & ) optional_noexcept -{ - return true; -} - -template< typename T > bool operator>( optional const & x, nullopt_t ) optional_noexcept -{ - return bool(x); -} - -template< typename T > bool operator>( nullopt_t, optional const & ) optional_noexcept -{ - return false; -} - -template< typename T > bool operator>=( optional const &, nullopt_t ) -{ - return true; -} - -template< typename T > bool operator>=( nullopt_t, optional const & x ) -{ - return (!x); -} - -// Comparison with T - -template< typename T > bool operator==( optional const & x, const T& v ) -{ - return bool(x) ? *x == v : false; -} - -template< typename T > bool operator==( T const & v, optional const & x ) -{ - return bool(x) ? v == *x : false; -} - -template< typename T > bool operator!=( optional const & x, const T& v ) -{ - return bool(x) ? *x != v : true; -} - -template< typename T > bool operator!=( T const & v, optional const & x ) -{ - return bool(x) ? v != *x : true; -} - -template< typename T > bool operator<( optional const & x, const T& v ) -{ - return bool(x) ? *x < v : true; -} - -template< typename T > bool operator<( T const & v, optional const & x ) -{ - return bool(x) ? v < *x : false; -} - -template< typename T > bool operator<=( optional const & x, const T& v ) -{ - return bool(x) ? *x <= v : true; -} - -template< typename T > bool operator<=( T const & v, optional const & x ) -{ - return bool(x) ? v <= *x : false; -} - -template< typename T > bool operator>( optional const & x, const T& v ) -{ - return bool(x) ? *x > v : false; -} - -template< typename T > bool operator>( T const & v, optional const & x ) -{ - return bool(x) ? v > *x : true; -} - -template< typename T > bool operator>=( optional const & x, const T& v ) -{ - return bool(x) ? *x >= v : false; -} - -template< typename T > bool operator>=( T const & v, optional const & x ) -{ - return bool(x) ? v >= *x : true; -} - -// Specialized algorithms - -template< typename T > -void swap( optional & x, optional & y ) -#if optional_CPP11_OR_GREATER - noexcept( noexcept( x.swap(y) ) ) -#endif -{ - x.swap( y ); -} - -#if optional_CPP11_OR_GREATER - -template< class T > -optional_constexpr optional< typename std::decay::type > make_optional( T && v ) -{ - return optional< typename std::decay::type >( std::forward( v ) ); -} - -template< class T, class...Args > -optional_constexpr optional make_optional( Args&&... args ) -{ - return optional( in_place, std::forward(args)...); -} - -template< class T, class U, class... Args > -optional_constexpr optional make_optional( std::initializer_list il, Args&&... args ) -{ - return optional( in_place, il, std::forward(args)...); -} - -#else - -template< typename T > -optional make_optional( T const & v ) -{ - return optional( v ); -} - -#endif // optional_CPP11_OR_GREATER - -} // namespace optional - -using namespace optional_lite; - -} // namespace nonstd - -#if optional_CPP11_OR_GREATER - -// specialize the std::hash algorithm: - -namespace std { - -template< class T > -struct hash< nonstd::optional > -{ -public: - std::size_t operator()( nonstd::optional const & v ) const optional_noexcept - { - return bool( v ) ? hash()( *v ) : 0; - } -}; - -} //namespace std - -#endif // optional_CPP11_OR_GREATER - -#endif // NONSTD_OPTIONAL_LITE_HPP diff --git a/src/solvers/flattening/boolbv_overflow.cpp b/src/solvers/flattening/boolbv_overflow.cpp index f9a0a3ea188..dcebd389089 100644 --- a/src/solvers/flattening/boolbv_overflow.cpp +++ b/src/solvers/flattening/boolbv_overflow.cpp @@ -118,7 +118,7 @@ literalt boolbvt::convert_binary_overflow(const binary_overflow_exprt &expr) expr.rhs(), can_cast_expr(expr) ? optionalt{bv0.size()} - : nullopt); + : std::nullopt); const bv_utilst::representationt rep = can_cast_type(expr.lhs().type()) diff --git a/src/solvers/flattening/boolbv_width.h b/src/solvers/flattening/boolbv_width.h index d50c433109e..24c8909fe00 100644 --- a/src/solvers/flattening/boolbv_width.h +++ b/src/solvers/flattening/boolbv_width.h @@ -32,7 +32,7 @@ class boolbv_widtht { const auto &entry_opt = get_entry(type); if(!entry_opt.has_value()) - return {}; + return std::nullopt; return entry_opt->total_width; } diff --git a/src/solvers/strings/string_dependencies.h b/src/solvers/strings/string_dependencies.h index 03a455117eb..ce06aa64143 100644 --- a/src/solvers/strings/string_dependencies.h +++ b/src/solvers/strings/string_dependencies.h @@ -164,8 +164,7 @@ class string_dependenciest // NOLINTNEXTLINE(readability/identifiers) struct node_hash { - size_t - operator()(const string_dependenciest::nodet &node) const optional_noexcept + size_t operator()(const string_dependenciest::nodet &node) const { return 2 * node.index + (node.kind == string_dependenciest::nodet::STRING ? 0 : 1); diff --git a/src/util/arith_tools.h b/src/util/arith_tools.h index 9d80873b30c..d5aa518b05d 100644 --- a/src/util/arith_tools.h +++ b/src/util/arith_tools.h @@ -94,7 +94,7 @@ struct numeric_castt(get_val(mpi)); else - return {}; + return std::nullopt; } // Conversion from expression @@ -103,7 +103,7 @@ struct numeric_castt{}(to_constant_expr(expr)); else - return {}; + return std::nullopt; } // Conversion from expression @@ -112,7 +112,7 @@ struct numeric_castt{}(expr)) return numeric_castt{}(*mpi_opt); else - return {}; + return std::nullopt; } }; diff --git a/src/util/module_dependencies.txt b/src/util/module_dependencies.txt index a0f86e99c8f..5300da7dfd3 100644 --- a/src/util/module_dependencies.txt +++ b/src/util/module_dependencies.txt @@ -1,6 +1,5 @@ big-int mach # system malloc # system -nonstd sys # system util diff --git a/src/util/numbering.h b/src/util/numbering.h index ea9fc6e94eb..b12ae04e6f3 100644 --- a/src/util/numbering.h +++ b/src/util/numbering.h @@ -52,7 +52,7 @@ class numberingt final const auto it = numbers_.find(a); if(it == numbers_.end()) { - return {}; + return std::nullopt; } return it->second; } diff --git a/src/util/optional.h b/src/util/optional.h index 3581e3d9f31..5cf349d2971 100644 --- a/src/util/optional.h +++ b/src/util/optional.h @@ -1,7 +1,7 @@ /*******************************************************************\ -Module: typedef for optional class template. To be replaced with - std::optional once C++17 support is enabled +Module: typedef for optional class template. New code should directly + use std::optional. Author: Diffblue Ltd. @@ -10,49 +10,18 @@ Author: Diffblue Ltd. #ifndef CPROVER_UTIL_OPTIONAL_H #define CPROVER_UTIL_OPTIONAL_H -#if defined __clang__ - #pragma clang diagnostic push ignore "-Wall" - #pragma clang diagnostic push ignore "-Wpedantic" -#elif defined __GNUC__ - #pragma GCC diagnostic push ignore "-Wall" - #pragma GCC diagnostic push ignore "-Wpedantic" -#elif defined _MSC_VER - #pragma warning(push) -#endif -#include -#if defined __clang__ - #pragma clang diagnostic pop - #pragma clang diagnostic pop -#elif defined __GNUC__ - #pragma GCC diagnostic pop - #pragma GCC diagnostic pop -#elif defined _MSC_VER - #pragma warning(pop) -#endif - -// Swap for std::optional when switching to C++17 -template -using optionalt=nonstd::optional; // NOLINT template typedef - -typedef nonstd::bad_optional_access bad_optional_accesst; +#include "deprecate.h" -using nonstd::nullopt; +#include -/// Similar to optionalt::value but in case of empty optional, generates an -/// invariant failure instead of throwing an exception. template -T &get_value_or_abort(optionalt &opt) -{ - PRECONDITION(opt.has_value()); - return opt.value(); -} - -/// \copydoc get_value_or_abort(optionalt &) -template -const T &get_value_or_abort(const optionalt &opt) -{ - PRECONDITION(opt.has_value()); - return opt.value(); -} +using optionalt +#ifndef _WIN32 + // Visual Studio doesn't support [deprecated] in this place + DEPRECATED(SINCE(2023, 11, 17, "directly use std::optional instead")) = +#else + = +#endif + std::optional; // NOLINT template typedef #endif // CPROVER_UTIL_OPTIONAL_H diff --git a/src/util/sharing_map.h b/src/util/sharing_map.h index 48158b29887..a45b693fad7 100644 --- a/src/util/sharing_map.h +++ b/src/util/sharing_map.h @@ -1454,7 +1454,7 @@ SHARING_MAPT2(optionalt>)::find( const nodet *lp = get_leaf_node(k); if(lp == nullptr) - return {}; + return std::nullopt; return optionalt>(lp->get_value()); } diff --git a/src/util/string2int.h b/src/util/string2int.h index ff6737aa688..0d9d71defe8 100644 --- a/src/util/string2int.h +++ b/src/util/string2int.h @@ -94,11 +94,11 @@ auto wrap_string_conversion(do_conversiont do_conversion) } catch(const std::invalid_argument &) { - return nullopt; + return std::nullopt; } catch(const std::out_of_range &) { - return nullopt; + return std::nullopt; } } diff --git a/unit/Makefile b/unit/Makefile index 208c3bc3a36..de364726e36 100644 --- a/unit/Makefile +++ b/unit/Makefile @@ -170,7 +170,6 @@ SRC += analyses/ai/ai.cpp \ util/lower_byte_operators.cpp \ util/memory_info.cpp \ util/message.cpp \ - util/optional.cpp \ util/optional_utils.cpp \ util/parse_options.cpp \ util/piped_process.cpp \ diff --git a/unit/util/optional.cpp b/unit/util/optional.cpp deleted file mode 100644 index bbaf6c6a97e..00000000000 --- a/unit/util/optional.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/*******************************************************************\ - -Module: nonstd::optional unit tests - -Author: Diffblue Ltd. - -\*******************************************************************/ - -#include -#include - -TEST_CASE("Optional without a value", "[core][util][optional]") -{ - optionalt maybe_value; - REQUIRE(!maybe_value.has_value()); - REQUIRE_THROWS_AS(maybe_value.value(), bad_optional_accesst); -} - -TEST_CASE("Optional with a value", "[core][util][optional]") -{ - optionalt maybe_value=false; - REQUIRE(maybe_value.has_value()); - REQUIRE(!maybe_value.value()); -} - - -TEST_CASE("Optional with a value (operator access)", "[core][util][optional]") -{ - optionalt maybe_value=true; - REQUIRE(maybe_value.has_value()); - REQUIRE(*maybe_value); -}