13 Commits

Author SHA1 Message Date
5c42d8fa3b Added library.json for platformio 2020-09-22 16:07:07 +02:00
0dfc7b4e41 Use add_library for subdirectory usage instead of add_executable 2019-11-11 10:56:36 +00:00
8177b93e7f Fix Travis for C++17 Clang builds 2019-10-25 14:40:28 +01:00
352b529889 Merge pull request #36 from slurps-mad-rips/cmake-revamp
Revamp CMake files to be more understandable and correct
2019-10-25 14:37:01 +01:00
e165e3554c Merge pull request #35 from IDragnev/fix_readme
Fix mistakes in README.md
2019-09-21 21:34:15 +01:00
c325c63b17 fixup! fixup! 🎨 Cleanup include path for catch2 2019-09-17 10:18:56 -07:00
dcebd5897f fixup! 🎨 Cleanup include path for catch2 2019-09-17 10:14:58 -07:00
54f7f970bf 🎨 Cleanup include path for catch2
 Add basic .deb generation support
WiX and RPM support is still needed for verification

⬆️ Upgrade minimum CMake version to 3.14
⬆️ Upgrade Catch to Catch v2.9.2
📌 Pin Catch to v2.9.1

👷 Update .travis.yml build matrix
👷 Update .appveyor build script

 Update tests to be separated by file
2019-09-17 09:59:36 -07:00
2673f3f9b3 Fix mistakes in README.md 2019-09-16 19:56:05 +03:00
83a0b49e5e Merge pull request #34 from denizevrenci/fix_emplace_on_ref
Fix implementation of optional<T&>::emplace()
2019-07-08 13:28:30 +01:00
ce266d5280 Add test 2019-07-08 20:07:06 +09:00
b074bee409 Fix implementation of optional<T&>::emplace() 2019-07-08 20:07:06 +09:00
084a9001f4 Add missing noexcept specifications to methods of optional<T&> 2019-07-08 20:07:06 +09:00
24 changed files with 341 additions and 12351 deletions

View File

@ -3,9 +3,6 @@ os:
- Visual Studio 2017
build_script:
- git submodule update --init --recursive
- mkdir build
- cd build
- cmake ..
- cmake --build .
- C:\projects\optional\build\Debug\tests.exe
- cmake -Bbuild -S.
- cmake --build build
- cmake --build build --target RUN_TESTS

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
\#*
.\#*
/build/

View File

@ -1,257 +1,161 @@
language: cpp
dist: xenial
sudo: false
matrix:
include:
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env: COMPILER=g++-5 CXXSTD=11
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env: COMPILER=g++-6 CXXSTD=11
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
env: COMPILER=g++-7 CXXSTD=11
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-8
env: COMPILER=g++-8 CXXSTD=11
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.9
env: COMPILER=g++-4.9 CXXSTD=11
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: g++-4.8 } }
env: COMPILER=g++-4.8 CXXSTD=11
- compiler: clang
- compiler: gcc
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: g++-4.9 } }
env: COMPILER=g++-4.9 CXXSTD=11
- &gcc-5
compiler: gcc
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: g++-5 } }
env: COMPILER=g++-5 CXXSTD=11
- &gcc-6
compiler: gcc
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: g++-6 } }
env: COMPILER=g++-6 CXXSTD=11
- &gcc-7
compiler: gcc
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: g++-7 } }
env: COMPILER=g++-7 CXXSTD=11
- &gcc-8
compiler: gcc
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: g++-8 } }
env: COMPILER=g++-8 CXXSTD=11
- &gcc-9
compiler: gcc
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: g++-9 } }
env: COMPILER=g++-9 CXXSTD=11
- &clang-35
compiler: clang
addons:
apt:
sources:
- llvm-toolchain-precise-3.5
- ubuntu-toolchain-r-test
packages:
- clang++-3.5
- libc++-dev
apt:
sources: [llvm-toolchain-precise-3.5, ubuntu-toolchain-r-test]
packages: [clang++-3.5, libc++-dev]
env: COMPILER=clang++-3.5 CXXSTD=11
- compiler: clang
- &clang-36
compiler: clang
addons:
apt:
sources:
- llvm-toolchain-precise-3.6
- ubuntu-toolchain-r-test
packages:
- clang++-3.6
- libc++-dev
apt:
sources: [llvm-toolchain-precise-3.6, ubuntu-toolchain-r-test]
packages: [clang++-3.6, libc++-dev]
env: COMPILER=clang++-3.6 CXXSTD=11
- compiler: clang
- &clang-37
compiler: clang
addons:
apt:
sources:
- llvm-toolchain-precise-3.7
- ubuntu-toolchain-r-test
packages:
- clang++-3.7
- libc++-dev
apt:
sources: [llvm-toolchain-precise-3.7, ubuntu-toolchain-r-test]
packages: [clang++-3.7, libc++-dev]
env: COMPILER=clang++-3.7 CXXSTD=11
- compiler: clang
- &clang-38
compiler: clang
addons:
apt:
sources:
- llvm-toolchain-precise-3.8
- ubuntu-toolchain-r-test
packages:
- clang++-3.8
- libc++-dev
- &xenial-clang
sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.8 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
packages: [clang++-3.8, libc++-dev]
env: COMPILER=clang++-3.8 CXXSTD=11
- compiler: clang
- &clang-39
compiler: clang
addons:
apt:
sources:
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main"
key_url: "http://apt.llvm.org/llvm-snapshot.gpg.key"
- <<: *xenial-clang
sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main'
- ubuntu-toolchain-r-test
packages:
- clang++-3.9
- libc++-dev
packages: [clang++-3.9, libc++-dev]
env: COMPILER=clang++-3.9 CXXSTD=11
- compiler: clang
- &clang-4
compiler: clang
addons:
apt:
sources:
- llvm-toolchain-xenial-4.0
- ubuntu-toolchain-r-test
packages:
- clang++-4.0
- libc++-dev
env: COMPILER=clang++-4.0 CXXSTD=11
- compiler: clang
addons:
apt:
sources:
- llvm-toolchain-xenial-5.0
- ubuntu-toolchain-r-test
packages:
- clang++-5.0
- libc++-dev
env: COMPILER=clang++-5.0 CXXSTD=11
- compiler: clang
addons:
apt:
sources:
- llvm-toolchain-xenial-6.0
- ubuntu-toolchain-r-test
packages:
- clang++-6.0
- libc++-dev
env: COMPILER=clang++-6.0 CXXSTD=11
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env: COMPILER=g++-5 CXXSTD=14
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env: COMPILER=g++-6 CXXSTD=14
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
env: COMPILER=g++-7 CXXSTD=14
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-8
env: COMPILER=g++-8 CXXSTD=14
- compiler: clang
addons:
apt:
sources:
- llvm-toolchain-precise-3.5
- ubuntu-toolchain-r-test
packages:
- clang++-3.5
- libc++-dev
env: COMPILER=clang++-3.5 CXXSTD=14
- compiler: clang
addons:
apt:
sources:
- llvm-toolchain-precise-3.6
- ubuntu-toolchain-r-test
packages:
- clang++-3.6
- libc++-dev
env: COMPILER=clang++-3.6 CXXSTD=14
- compiler: clang
addons:
apt:
sources:
- llvm-toolchain-precise-3.7
- ubuntu-toolchain-r-test
packages:
- clang++-3.7
- libc++-dev
env: COMPILER=clang++-3.7 CXXSTD=14
- compiler: clang
addons:
apt:
sources:
- llvm-toolchain-precise-3.8
- ubuntu-toolchain-r-test
packages:
- clang++-3.8
- libc++-dev
env: COMPILER=clang++-3.8 CXXSTD=14
- compiler: clang
addons:
apt:
sources:
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main"
key_url: "http://apt.llvm.org/llvm-snapshot.gpg.key"
- <<: *xenial-clang
sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main'
- ubuntu-toolchain-r-test
packages:
- clang++-3.9
- libc++-dev
env: COMPILER=clang++-3.9 CXXSTD=14
- compiler: clang
packages: [clang++-4.0, libc++-dev]
env: COMPILER=clang++-4.0 CXXSTD=11
- &clang-5
compiler: clang
addons:
apt:
sources:
- llvm-toolchain-xenial-4.0
- ubuntu-toolchain-r-test
packages:
- clang++-4.0
- libc++-dev
env: COMPILER=clang++-4.0 CXXSTD=14
- compiler: clang
- <<: *xenial-clang
sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-5.0 main'
- ubuntu-toolchain-r-test
packages: [clang++-5.0, libc++-dev]
env: COMPILER=clang++-5.0 CXXSTD=11
- &clang-6
compiler: clang
addons:
apt:
sources: [llvm-toolchain-xenial-6.0, ubuntu-toolchain-r-test]
packages: [clang++-6.0, libc++-dev]
env: COMPILER=clang++-6.0 CXXSTD=11
- &clang-7
compiler: clang
addons:
apt:
sources: [llvm-toolchain-xenial-7, ubuntu-toolchain-r-test]
packages: [clang++-7, libc++-7-dev, libc++abi-7-dev]
env: COMPILER=clang++-7 CXXSTD=11
- &clang-8
compiler: clang
addons:
apt:
sources: [llvm-toolchain-xenial-8, ubuntu-toolchain-r-test]
packages: [clang++-8, libc++-8-dev, libc++abi-8-dev]
env: COMPILER=clang++-8 CXXSTD=11
- &clang-9
compiler: clang
addons:
apt:
sources:
- llvm-toolchain-xenial-5.0
- ubuntu-toolchain-r-test
packages:
- clang++-5.0
- libc++-dev
env: COMPILER=clang++-5.0 CXXSTD=14
- compiler: clang
addons:
apt:
sources:
- llvm-toolchain-xenial-6.0
- ubuntu-toolchain-r-test
packages:
- clang++-6.0
- libc++-dev
env: COMPILER=clang++-6.0 CXXSTD=14
- <<: *xenial-clang
sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
- ubuntu-toolchain-r-test
packages: [clang++-9, libc++-9-dev, libc++abi-9-dev]
env: COMPILER=clang++-9 CXXSTD=11
- { <<: *gcc-5, env: COMPILER=g++-5 CXXSTD=14 }
- { <<: *gcc-6, env: COMPILER=g++-6 CXXSTD=14 }
- { <<: *gcc-7, env: COMPILER=g++-7 CXXSTD=14 }
- { <<: *gcc-8, env: COMPILER=g++-8 CXXSTD=14 }
- { <<: *gcc-9, env: COMPILER=g++-9 CXXSTD=14 }
- { <<: *gcc-7, env: COMPILER=g++-7 CXXSTD=17 }
- { <<: *gcc-8, env: COMPILER=g++-8 CXXSTD=17 }
- { <<: *gcc-9, env: COMPILER=g++-9 CXXSTD=17 }
- { <<: *clang-35, env: COMPILER=clang++-3.5 CXXSTD=14 }
- { <<: *clang-36, env: COMPILER=clang++-3.6 CXXSTD=14 }
- { <<: *clang-37, env: COMPILER=clang++-3.7 CXXSTD=14 }
- { <<: *clang-38, env: COMPILER=clang++-3.8 CXXSTD=14 }
- { <<: *clang-39, env: COMPILER=clang++-3.9 CXXSTD=14 }
- { <<: *clang-4, env: COMPILER=clang++-4.0 CXXSTD=14 }
- { <<: *clang-5, env: COMPILER=clang++-5.0 CXXSTD=14 }
- { <<: *clang-6, env: COMPILER=clang++-6.0 CXXSTD=14 }
- { <<: *clang-7, env: COMPILER=clang++-7 CXXSTD=14 }
- { <<: *clang-8, env: COMPILER=clang++-8 CXXSTD=14 }
- { <<: *clang-9, env: COMPILER=clang++-9 CXXSTD=14 }
- { <<: *clang-7, env: COMPILER=clang++-7 CXXSTD=17 }
- { <<: *clang-8, env: COMPILER=clang++-8 CXXSTD=17 }
- { <<: *clang-9, env: COMPILER=clang++-9 CXXSTD=17 }
before_install:
- sudo apt update
- sudo apt install -y apt-transport-https ca-certificates gnupg software-properties-common
- curl -L https://apt.kitware.com/keys/kitware-archive-latest.asc | sudo apt-key add -
- sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ xenial main'
- sudo apt update
install:
- if [ "$CXX" = "clang++" ]; then export CXX="$COMPILER -stdlib=libc++"; fi
- if [ "$CXX" = "g++" ]; then export CXX="$COMPILER"; fi
- sudo apt install -y cmake
script: mkdir build && cd build && cmake -DCXXSTD=$CXXSTD .. && make && ./tests
script:
- /usr/bin/cmake -B build -S . "-DCMAKE_CXX_STANDARD=$CXXSTD" "-DCMAKE_CXX_COMPILER=$COMPILER"
- /usr/bin/cmake --build build
- /usr/bin/cmake --build build --target test

View File

@ -1,52 +1,145 @@
cmake_minimum_required(VERSION 3.11)
project(tl-optional VERSION 1.0.0 LANGUAGES CXX)
option(OPTIONAL_ENABLE_TESTS "Enable tests." ON)
cmake_minimum_required(VERSION 3.14)
project(tl-optional
HOMEPAGE_URL https://tl.tartanllama.xyz
DESCRIPTION "C++11/14/17 std::optional with functional-style extensions and reference support"
VERSION 1.0.0
LANGUAGES CXX)
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)
include(GNUInstallDirs)
include(FetchContent)
FetchContent_Declare(
tl_cmake
GIT_REPOSITORY https://github.com/TartanLlama/tl-cmake.git
)
FetchContent_GetProperties(tl_cmake)
if(NOT tl_cmake_POPULATED)
FetchContent_Populate(tl_cmake)
set(CMAKE_MODULE_PATH ${tl_cmake_SOURCE_DIR} ${CMAKE_MODULE_PATH})
endif()
include(add-tl)
include(CTest)
tl_add_library(optional SOURCES
include/tl/optional.hpp)
find_program(DPKG_BUILDPACKAGE_FOUND dpkg-buildpackage)
find_program(RPMBUILD_FOUND rpmbuild)
if(OPTIONAL_ENABLE_TESTS)
# Prepare "Catch" library for other executables
set(CATCH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test)
add_library(Catch INTERFACE)
target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
# Make test executable
set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/noexcept.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/make_optional.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/in_place.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/relops.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/observers.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/extensions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/emplace.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/constexpr.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/constructors.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/assignment.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/issues.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/bases.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/nullopt.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/swap.cpp)
add_executable(tests ${TEST_SOURCES})
target_link_libraries(tests Catch optional)
set(CXXSTD 14 CACHE STRING "C++ standard to use, default C++14")
set_property(TARGET tests PROPERTY CXX_STANDARD ${CXXSTD})
if (NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
option(OPTIONAL_BUILD_PACKAGE "Build packages" ON)
cmake_dependent_option(OPTIONAL_BUILD_TESTS
"Enable tl::optional tests" ON
"BUILD_TESTING" OFF)
cmake_dependent_option(OPTIONAL_BUILD_PACKAGE_DEB
"Create DEB Package (${PROJECT_NAME})" ON
"OPTIONAL_BUILD_PACKAGE;DPKG_BUILDPACKAGE_FOUND" OFF)
cmake_dependent_option(OPTIONAL_BUILD_PACKAGE_RPM
"Create RPM Package (${PROJECT_NAME})" ON
"OPTIONAL_BUILD_PACKAGE;RPMBUILD_FOUND" OFF)
cmake_dependent_option(OPTIONAL_BUILD_PACKAGE_MSI
"Create MSI (${PROJECT_NAME})" ON
"OPTIONAL_BUILD_PACKAGE;CMAKE_HOST_WIN32" OFF)
add_library(optional INTERFACE)
target_include_directories(optional
INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
if (NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
add_library(tl::optional ALIAS optional)
endif()
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}-config.cmake.in"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}")
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
COMPATIBILITY SameMajorVersion
ARCH_INDEPENDENT)
install(TARGETS optional EXPORT ${PROJECT_NAME}-targets)
install(EXPORT ${PROJECT_NAME}-targets
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}"
NAMESPACE tl::
FILE "${PROJECT_NAME}-targets.cmake")
install(FILES
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}")
install(DIRECTORY "include/" TYPE INCLUDE)
if (OPTIONAL_BUILD_TESTS)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
set(CATCH_INSTALL_HELPERS OFF)
set(CATCH_BUILD_TESTING OFF)
set(CATCH_INSTALL_DOCS OFF)
FetchContent_Declare(Catch2 URL
https://github.com/catchorg/Catch2/archive/v2.9.2.zip)
FetchContent_MakeAvailable(Catch2)
file(GENERATE OUTPUT catch.main.cpp
CONTENT [[
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
]])
set_property(SOURCE ${PROJECT_BINARY_DIR}/catch.main.cpp
PROPERTY
GENERATED ON)
add_library(${PROJECT_NAME}-catch-main OBJECT)
target_sources(${PROJECT_NAME}-catch-main PRIVATE
${PROJECT_BINARY_DIR}/catch.main.cpp)
target_compile_options(${PROJECT_NAME}-catch-main
PUBLIC
$<$<AND:$<CXX_COMPILER_ID:Clang>,$<BOOL:"$ENV{TRAVIS}">>:-stdlib=libc++>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra>)
target_link_options(${PROJECT_NAME}-catch-main
PUBLIC
$<$<AND:$<CXX_COMPILER_ID:Clang>,$<BOOL:"$ENV{TRAVIS}">>:-stdlib=libc++>)
target_link_libraries(${PROJECT_NAME}-catch-main
PUBLIC
Catch2::Catch2
optional)
file(GLOB test-sources CONFIGURE_DEPENDS tests/*.cpp)
foreach (source IN LISTS test-sources)
get_filename_component(name "${source}" NAME_WE)
set(test "${PROJECT_NAME}-test-${name}")
add_executable(${test}
"${source}"
$<TARGET_OBJECTS:${PROJECT_NAME}-catch-main>)
target_link_libraries(${test}
PRIVATE
${PROJECT_NAME}-catch-main)
add_test(NAME ${PROJECT_NAME}::test::${name} COMMAND ${test})
endforeach()
endif()
if (NOT OPTIONAL_BUILD_PACKAGE)
return()
endif()
list(APPEND source-generators TBZ2 TGZ TXZ ZIP)
if (OPTIONAL_BUILD_PACKAGE_MSI)
list(APPEND binary-generators "WIX")
endif()
if (OPTIONAL_BUILD_PACKAGE_DEB)
list(APPEND binary-generators "DEB")
endif()
if (OPTIONAL_BUILD_PACKAGE_RPM)
list(APPEND binary-generators "RPM")
endif()
set(CPACK_SOURCE_GENERATOR ${source-generators})
set(CPACK_GENERATOR ${binary-generators})
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILENAME}")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Sy Brand")
list(APPEND CPACK_SOURCE_IGNORE_FILES /.git/ /build/ .gitignore .DS_Store)
include(CPack)

View File

@ -56,10 +56,10 @@ The interface is the same as `std::optional`, but the following member functions
* `tl::optional<std::size_t> s = opt_string.map_or(&std::string::size, 0);`
- `map_or_else`: carries out a `map` if there is a value, otherwise returns the result of a given default function.
* `std::size_t get_default();`
* `tl::optional<std::size_t> s = opt_string.map_or(&std::string::size, get_default);`
* `tl::optional<std::size_t> s = opt_string.map_or_else(&std::string::size, get_default);`
- `conjunction`: returns the argument if a value is stored in the optional, otherwise an empty optional.
* `tl::make_optional(42).conjunction(13); //13`
* `tl::optional<int>){}.conjunction(13); //empty`
* `tl::optional<int>{}.conjunction(13); //empty`
- `disjunction`: returns the argument if the optional is empty, otherwise the current value.
* `tl::make_optional(42).disjunction(13); //42`
* `tl::optional<int>{}.disjunction(13); //13`
@ -73,7 +73,7 @@ int i = 42;
tl::optional<int&> o = i;
*o == 42; //true
i = 12;
*o = 12; //true
*o == 12; //true
&*o == &i; //true
```

View File

@ -1939,12 +1939,12 @@ public:
template <class U = T,
detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>
* = nullptr>
constexpr optional(U &&u) : m_value(std::addressof(u)) {
constexpr optional(U &&u) noexcept : m_value(std::addressof(u)) {
static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
}
template <class U>
constexpr explicit optional(const optional<U> &rhs) : optional(*rhs) {}
constexpr explicit optional(const optional<U> &rhs) noexcept : optional(*rhs) {}
/// No-op
~optional() = default;
@ -1977,33 +1977,30 @@ public:
///
/// Rebinds this optional to the referee of `rhs` if there is one. Otherwise
/// resets the stored value in `*this`.
template <class U> optional &operator=(const optional<U> &rhs) {
template <class U> optional &operator=(const optional<U> &rhs) noexcept {
m_value = std::addressof(rhs.value());
return *this;
}
/// Constructs the value in-place, destroying the current one if there is
/// one.
template <class... Args> T &emplace(Args &&... args) noexcept {
static_assert(std::is_constructible<T, Args &&...>::value,
"T must be constructible with Args");
*this = nullopt;
this->construct(std::forward<Args>(args)...);
return value();
/// Rebinds this optional to `u`.
template <class U = T,
detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>
* = nullptr>
optional &emplace(U &&u) noexcept {
return *this = std::forward<U>(u);
}
void swap(optional &rhs) noexcept { std::swap(m_value, rhs.m_value); }
/// Returns a pointer to the stored value
constexpr const T *operator->() const { return m_value; }
constexpr const T *operator->() const noexcept { return m_value; }
TL_OPTIONAL_11_CONSTEXPR T *operator->() { return m_value; }
TL_OPTIONAL_11_CONSTEXPR T *operator->() noexcept { return m_value; }
/// Returns the stored value
TL_OPTIONAL_11_CONSTEXPR T &operator*() { return *m_value; }
TL_OPTIONAL_11_CONSTEXPR T &operator*() noexcept { return *m_value; }
constexpr const T &operator*() const { return *m_value; }
constexpr const T &operator*() const noexcept { return *m_value; }
constexpr bool has_value() const noexcept { return m_value != nullptr; }
@ -2024,7 +2021,7 @@ public:
}
/// Returns the stored value if there is one, otherwise returns `u`
template <class U> constexpr T value_or(U &&u) const & {
template <class U> constexpr T value_or(U &&u) const & noexcept {
static_assert(std::is_copy_constructible<T>::value &&
std::is_convertible<U &&, T>::value,
"T must be copy constructible and convertible from U");
@ -2032,7 +2029,7 @@ public:
}
/// \group value_or
template <class U> TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u) && {
template <class U> TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u) && noexcept {
static_assert(std::is_move_constructible<T>::value &&
std::is_convertible<U &&, T>::value,
"T must be move constructible and convertible from U");

13
library.json Normal file
View File

@ -0,0 +1,13 @@
{
"name": "optional",
"version": "1.0.0",
"build": {
"includeDir": "include",
"srcFilter": [
"+<*>",
"-<.git>",
"-<cmake/>",
"-<tests/*>"
]
}
}

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
TEST_CASE("Assignment value", "[assignment.value]") {

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
// Old versions of GCC don't have the correct trait names. Could fix them up if needs be.

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,6 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
#define TOKENPASTE(x, y) x##y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define STATIC_REQUIRE(e) \
constexpr bool TOKENPASTE2(rqure, __LINE__) = e; \
REQUIRE(e);
TEST_CASE("Constexpr", "[constexpr]") {
#if !defined(TL_OPTIONAL_MSVC2015) && defined(TL_OPTIONAL_CXX14)
SECTION("empty construct") {

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
#include <vector>

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
#include <utility>
#include <tuple>

View File

@ -1,13 +1,7 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
#include <string>
#define TOKENPASTE(x, y) x##y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define STATIC_REQUIRE(e) \
constexpr bool TOKENPASTE2(rqure, __LINE__) = e; \
REQUIRE(e);
constexpr int get_int(int) { return 42; }
TL_OPTIONAL_11_CONSTEXPR tl::optional<int> get_opt_int(int) { return 42; }
@ -49,7 +43,7 @@ TEST_CASE("Monadic operations", "[monadic]") {
// test void return
tl::optional<int> o7 = 40;
auto f7 = [](const int &i) { return; };
auto f7 = [](const int &) { return; };
auto o7r = o7.map(f7);
STATIC_REQUIRE(
(std::is_same<decltype(o7r), tl::optional<tl::monostate>>::value));
@ -188,7 +182,7 @@ TEST_CASE("Monadic operations", "[monadic]") {
// test void return
tl::optional<int> o7 = 40;
auto f7 = [](const int& i) { return; };
auto f7 = [](const int&) { return; };
auto o7r = o7.transform(f7);
STATIC_REQUIRE(
(std::is_same<decltype(o7r), tl::optional<tl::monostate>>::value));
@ -295,25 +289,25 @@ TEST_CASE("Monadic operations", "[monadic]") {
// lhs is empty
tl::optional<int> o1;
auto o1r = o1.and_then([](int i) { return tl::optional<float>{42}; });
auto o1r = o1.and_then([](int) { return tl::optional<float>{42}; });
STATIC_REQUIRE((std::is_same<decltype(o1r), tl::optional<float>>::value));
REQUIRE(!o1r);
// lhs has value
tl::optional<int> o2 = 12;
auto o2r = o2.and_then([](int i) { return tl::optional<float>{42}; });
auto o2r = o2.and_then([](int) { return tl::optional<float>{42}; });
STATIC_REQUIRE((std::is_same<decltype(o2r), tl::optional<float>>::value));
REQUIRE(o2r.value() == 42.f);
// lhs is empty, rhs returns empty
tl::optional<int> o3;
auto o3r = o3.and_then([](int i) { return tl::optional<float>{}; });
auto o3r = o3.and_then([](int) { return tl::optional<float>{}; });
STATIC_REQUIRE((std::is_same<decltype(o3r), tl::optional<float>>::value));
REQUIRE(!o3r);
// rhs returns empty
tl::optional<int> o4 = 12;
auto o4r = o4.and_then([](int i) { return tl::optional<float>{}; });
auto o4r = o4.and_then([](int) { return tl::optional<float>{}; });
STATIC_REQUIRE((std::is_same<decltype(o4r), tl::optional<float>>::value));
REQUIRE(!o4r);
@ -345,38 +339,38 @@ TEST_CASE("Monadic operations", "[monadic]") {
// test each overload in turn
tl::optional<int> o8 = 42;
auto o8r = o8.and_then([](int i) { return tl::make_optional(42); });
auto o8r = o8.and_then([](int) { return tl::make_optional(42); });
REQUIRE(*o8r == 42);
tl::optional<int> o9 = 42;
auto o9r =
std::move(o9).and_then([](int i) { return tl::make_optional(42); });
std::move(o9).and_then([](int) { return tl::make_optional(42); });
REQUIRE(*o9r == 42);
const tl::optional<int> o10 = 42;
auto o10r = o10.and_then([](int i) { return tl::make_optional(42); });
auto o10r = o10.and_then([](int) { return tl::make_optional(42); });
REQUIRE(*o10r == 42);
const tl::optional<int> o11 = 42;
auto o11r =
std::move(o11).and_then([](int i) { return tl::make_optional(42); });
std::move(o11).and_then([](int) { return tl::make_optional(42); });
REQUIRE(*o11r == 42);
tl::optional<int> o16 = tl::nullopt;
auto o16r = o16.and_then([](int i) { return tl::make_optional(42); });
auto o16r = o16.and_then([](int) { return tl::make_optional(42); });
REQUIRE(!o16r);
tl::optional<int> o17 = tl::nullopt;
auto o17r =
std::move(o17).and_then([](int i) { return tl::make_optional(42); });
std::move(o17).and_then([](int) { return tl::make_optional(42); });
REQUIRE(!o17r);
const tl::optional<int> o18 = tl::nullopt;
auto o18r = o18.and_then([](int i) { return tl::make_optional(42); });
auto o18r = o18.and_then([](int) { return tl::make_optional(42); });
REQUIRE(!o18r);
const tl::optional<int> o19 = tl::nullopt;
auto o19r = std::move(o19).and_then([](int i) { return tl::make_optional(42); });
auto o19r = std::move(o19).and_then([](int) { return tl::make_optional(42); });
REQUIRE(!o19r);
int i = 3;

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
TEST_CASE("Hashing", "[hash]") {}

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
#include <tuple>

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
#include <type_traits>
@ -31,4 +31,15 @@ TEST_CASE("issue 15") {
o = o;
REQUIRE(o->value == 42);
}
}
TEST_CASE("issue 33") {
int i = 0;
int j = 0;
tl::optional<int&> a = i;
a.emplace(j);
*a = 42;
REQUIRE(j == 42);
REQUIRE(*a == 42);
REQUIRE(a.has_value());
}

View File

@ -1,2 +0,0 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
#include <tuple>

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
TEST_CASE("Noexcept", "[noexcept]") {
@ -48,7 +48,7 @@ TEST_CASE("Noexcept", "[noexcept]") {
SECTION("constructors") {
//TODO see why this fails
#if !defined(_MSC_VER) || _MSC_VER >= 1900
#if !defined(_MSC_VER) || _MSC_VER > 1900
REQUIRE(noexcept(tl::optional<int>{}));
REQUIRE(noexcept(tl::optional<int>{tl::nullopt}));

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
TEST_CASE("Nullopt", "[nullopt]") {

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
struct move_detector {

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
TEST_CASE("Relational ops", "[relops]") {

View File

@ -1,4 +1,4 @@
#include "catch.hpp"
#include <catch2/catch.hpp>
#include <tl/optional.hpp>
TEST_CASE("Swap value", "[swap.value]") {