init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled

This commit is contained in:
allhaileris
2026-02-16 15:50:16 +03:00
commit afb81b8278
13816 changed files with 3689732 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
# Configuration file for EditorConfig, see https://EditorConfig.org
# Ignore any other files further up in the file system
root = true
# All files:
[*]
# Let git determine line ending: end_of_line = lf
charset = utf-8
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
# Markdown files: keep trailing space-pair as line-break
[*.md]
trim_trailing_whitespace = false
# Python scripts:
[*.py]
# YAML scripts:
[*.yml]
indent_size = 2
# Makefiles: Tab indentation (no size specified)
[Makefile]
indent_style = tab
# C, C++ source files:
[*.{h,hpp,c,cpp}]

View File

@@ -0,0 +1,26 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for CodeBlocks
*.cbp text eol=lf
*.workspace text eol=lf
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

View File

@@ -0,0 +1,97 @@
name: CI
env:
PROJECT: EXPECTED_LITE
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
jobs:
gcc:
strategy:
matrix:
version: [8, 9, 10, 11]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install GCC ${{ matrix.version }}
run: sudo apt-get install -y gcc-${{ matrix.version }} g++-${{ matrix.version }}
- name: Configure tests
env:
CXX: g++-${{ matrix.version }}
run: cmake -S . -B build
-D CMAKE_BUILD_TYPE:STRING=Release
-D ${{ env.PROJECT }}_OPT_SELECT_NONSTD=ON
-D ${{ env.PROJECT }}_OPT_BUILD_TESTS=ON
-D ${{ env.PROJECT }}_OPT_BUILD_EXAMPLES=OFF
- name: Build tests
run: cmake --build build -j 4
- name: Run tests
working-directory: build
run: ctest --output-on-failure -j 4
clang:
strategy:
matrix:
version: [8, 9, 10, 11, 12]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Clang ${{ matrix.version }}
run: sudo apt-get install -y clang-${{ matrix.version }}
- name: Configure tests
env:
CXX: clang-${{ matrix.version }}
run: cmake -S . -B build
-D CMAKE_CXX_COMPILER=clang++
-D CMAKE_BUILD_TYPE:STRING=Release
-D ${{ env.PROJECT }}_OPT_SELECT_NONSTD=ON
-D ${{ env.PROJECT }}_OPT_BUILD_TESTS=ON
-D ${{ env.PROJECT }}_OPT_BUILD_EXAMPLES=OFF
- name: Build tests
run: cmake --build build -j 4
- name: Run tests
working-directory: build
run: ctest --output-on-failure -j 4
msvc:
strategy:
matrix:
os: [windows-2019, windows-2022]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Configure tests
run: cmake -S . -B build
-D ${{ env.PROJECT }}_OPT_SELECT_NONSTD=ON
-D ${{ env.PROJECT }}_OPT_BUILD_TESTS=ON
-D ${{ env.PROJECT }}_OPT_BUILD_EXAMPLES=OFF
- name: Build tests
run: cmake --build build --config Release -j 4
- name: Run tests
working-directory: build
run: ctest -C Release --output-on-failure -j 4

View File

@@ -0,0 +1,41 @@
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
test/expected.t
# Build folder
/build/
# CodeBlocks IDE files
*.layout
# Visual Studio Code
/.vscode/
# Visual Studio
/.vs/

View File

@@ -0,0 +1,4 @@
[bugtraq]
url = https://github.com/martinmoene/expected-lite/issues/%BUGID%
number = true
logregex = "(\\s*(,|and)?\\s*#\\d+)+\n(\\d+)"

View File

@@ -0,0 +1,166 @@
os: linux
dist: trusty
sudo: false
group: travis_latest
language: c++
cache: ccache
addons:
apt:
sources: &apt_sources
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- llvm-toolchain-precise-3.6
- llvm-toolchain-precise-3.7
- llvm-toolchain-precise-3.8
- llvm-toolchain-trusty-3.9
- llvm-toolchain-trusty-4.0
- llvm-toolchain-trusty-5.0
- llvm-toolchain-trusty-6.0
matrix:
include:
- os: linux
env: COMPILER=g++-4.8
compiler: gcc
addons: &gcc4_8
apt:
packages: ["g++-4.8", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=g++-4.9
compiler: gcc
addons: &gcc4_9
apt:
packages: ["g++-4.9", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=g++-5
compiler: gcc
addons: &gcc5
apt:
packages: ["g++-5", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=g++-6
compiler: gcc
addons: &gcc6
apt:
packages: ["g++-6", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=g++-7
compiler: gcc
addons: &gcc7
apt:
packages: ["g++-7", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=g++-8
compiler: gcc
addons: &gcc8
apt:
packages: ["g++-8", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=clang++-3.5
compiler: clang
addons: &clang3_5
apt:
packages: ["clang-3.5", "g++-7", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=clang++-3.6
compiler: clang
addons: &clang3_6
apt:
packages: ["clang-3.6", "g++-7", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=clang++-3.7
compiler: clang
addons: &clang3-7
apt:
packages: ["clang-3.7", "g++-7", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=clang++-3.8
compiler: clang
addons: &clang3_8
apt:
packages: ["clang-3.8", "g++-7", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=clang++-3.9
compiler: clang
addons: &clang3_9
apt:
packages: ["clang-3.9", "g++-7", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=clang++-4.0
compiler: clang
addons: &clang4_0
apt:
packages: ["clang-4.0", "g++-7", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=clang++-5.0
compiler: clang
addons: &clang5_0
apt:
packages: ["clang-5.0", "g++-7", "python3-pip", "lcov"]
sources: *apt_sources
- os: linux
env: COMPILER=clang++-6.0
compiler: clang
addons: &clang6_0
apt:
packages: ["clang-6.0", "g++-7", "python3-pip", "lcov"]
sources: *apt_sources
- os: osx
osx_image: xcode7.3
compiler: clang
env: COMPILER='clang++'
- os: osx
osx_image: xcode8
compiler: clang
env: COMPILER='clang++'
- os: osx
osx_image: xcode9
compiler: clang
env: COMPILER='clang++'
- os: osx
osx_image: xcode10
compiler: clang
env: COMPILER='clang++'
allow_failures:
- env: COMPILER=clang++-3.5
fast_finish: true
script:
- export CXX=${COMPILER}
- JOBS=2 # Travis machines have 2 cores.
- mkdir build && cd build
- cmake -G "Unix Makefiles" -DEXPECTED_LITE_OPT_SELECT_NONSTD=ON -DEXPECTED_LITE_OPT_BUILD_TESTS=ON -DEXPECTED_LITE_OPT_BUILD_EXAMPLES=OFF ..
- cmake --build . -- -j${JOBS}
- ctest --output-on-failure -j${JOBS}

View File

@@ -0,0 +1,5 @@
Changes for expected lite
version 0.0 2016-03-13
- Initial code commit.

View File

@@ -0,0 +1,130 @@
# Copyright 2016-2018 by Martin Moene
#
# https://github.com/martinmoene/expected-lite
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
cmake_minimum_required( VERSION 3.5 FATAL_ERROR )
# expected-lite project and version, updated by script/update-version.py:
project(
expected_lite
VERSION 0.6.2
# DESCRIPTION "Expected objects in C++11 and later in a single-file header-only library"
# HOMEPAGE_URL "https://github.com/martinmoene/expected-lite"
LANGUAGES CXX )
# Package information:
set( unit_name "expected" )
set( package_nspace "nonstd" )
set( package_name "${unit_name}-lite" )
set( package_version "${${PROJECT_NAME}_VERSION}" )
message( STATUS "Project '${PROJECT_NAME}', package '${package_name}' version: '${package_version}'")
# Toplevel or subproject:
if ( CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME )
set( expected_IS_TOPLEVEL_PROJECT TRUE )
else()
set( expected_IS_TOPLEVEL_PROJECT FALSE )
endif()
# If toplevel project, enable building and performing of tests, disable building of examples:
option( EXPECTED_LITE_OPT_BUILD_TESTS "Build and perform expected-lite tests" ${expected_IS_TOPLEVEL_PROJECT} )
option( EXPECTED_LITE_OPT_BUILD_EXAMPLES "Build expected-lite examples" OFF )
set( EXPEXTED_P0323R "99" STRING "Specify proposal revision compatibility (99: latest)" )
option( EXPECTED_LITE_OPT_SELECT_STD "Select std::expected" OFF )
option( EXPECTED_LITE_OPT_SELECT_NONSTD "Select nonstd::expected" OFF )
# If requested, build and perform tests, build examples:
if ( EXPECTED_LITE_OPT_BUILD_TESTS )
enable_testing()
add_subdirectory( test )
endif()
if ( EXPECTED_LITE_OPT_BUILD_EXAMPLES )
add_subdirectory( example )
endif()
#
# Interface, installation and packaging
#
# CMake helpers:
include( GNUInstallDirs )
include( CMakePackageConfigHelpers )
# Interface library:
add_library(
${package_name} INTERFACE )
add_library(
${package_nspace}::${package_name} ALIAS ${package_name} )
target_include_directories(
${package_name}
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" )
# Package configuration:
# Note: package_name and package_target are used in package_config_in
set( package_folder "${package_name}" )
set( package_target "${package_name}-targets" )
set( package_config "${package_name}-config.cmake" )
set( package_config_in "${package_name}-config.cmake.in" )
set( package_config_version "${package_name}-config-version.cmake" )
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/${package_config_in}"
"${CMAKE_CURRENT_BINARY_DIR}/${package_config}"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${package_folder}"
)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/${package_config_version}.in"
"${CMAKE_CURRENT_BINARY_DIR}/${package_config_version}" @ONLY
)
# Installation:
install(
TARGETS ${package_name}
EXPORT ${package_target}
# INCLUDES DESTINATION "${...}" # already set via target_include_directories()
)
install(
EXPORT ${package_target}
NAMESPACE ${package_nspace}::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${package_folder}"
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/${package_config}"
"${CMAKE_CURRENT_BINARY_DIR}/${package_config_version}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${package_folder}"
)
install(
DIRECTORY "include/"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
export(
EXPORT ${package_target}
NAMESPACE ${package_nspace}::
FILE "${CMAKE_CURRENT_BINARY_DIR}/${package_name}-targets.cmake"
)
# end of file

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,9 @@
Plan
----
- [ ] Implement expected.then() etc.
- [x] Write CMake files
- [x] Check code against current Dxxxxr0 and adapt
- [x] Expand README.md
- [x] Expand test/expected.t.cpp
- [x] Improve use of travis matrix

View File

@@ -0,0 +1,459 @@
# expected lite: expected objects for C++11 and later
[![Language](https://img.shields.io/badge/C%2B%2B-11-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [![License](https://img.shields.io/badge/license-BSL-blue.svg)](https://opensource.org/licenses/BSL-1.0) [![Build Status](https://github.com/martinmoene/expected-lite/actions/workflows/ci.yml/badge.svg)](https://github.com/martinmoene/expected-lite/actions/workflows/ci.yml) [![Build Status](https://travis-ci.org/martinmoene/expected-lite.svg?branch=master)](https://travis-ci.org/martinmoene/expected-lite) [![Build status](https://ci.appveyor.com/api/projects/status/sle31w7obrm8lhe1?svg=true)](https://ci.appveyor.com/project/martinmoene/expected-lite) [![Version](https://badge.fury.io/gh/martinmoene%2Fexpected-lite.svg)](https://github.com/martinmoene/expected-lite/releases) [![download](https://img.shields.io/badge/latest-download-blue.svg)](https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp) [![Conan](https://img.shields.io/badge/on-conan-blue.svg)](https://conan.io/center/expected-lite) [![Try it online](https://img.shields.io/badge/on-wandbox-blue.svg)](https://wandbox.org/permlink/MnnwqOtE8ZQ4rRsv) [![Try it on godbolt online](https://img.shields.io/badge/on-godbolt-blue.svg)](https://godbolt.org/z/9BuMZx)
*expected lite* is a single-file header-only library for objects that either represent a valid value or an error that you can pass by value. It is intended for use with C++11 and later. The library is based on the [std:&#58;expected](http://wg21.link/p0323) proposal [1] .
**Contents**
- [Example usage](#example-usage)
- [In a nutshell](#in-a-nutshell)
- [License](#license)
- [Dependencies](#dependencies)
- [Installation](#installation)
- [Synopsis](#synopsis)
- [Comparison with like types](#comparison)
- [Reported to work with](#reported-to-work-with)
- [Implementation notes](#implementation-notes)
- [Other implementations of expected](#other-implementations-of-expected)
- [Notes and references](#notes-and-references)
- [Appendix](#appendix)
## Example usage
```Cpp
#include "nonstd/expected.hpp"
#include <cstdlib>
#include <iostream>
#include <string>
using namespace nonstd;
using namespace std::literals;
auto to_int( char const * const text ) -> expected<int, std::string>
{
char * pos = nullptr;
auto value = strtol( text, &pos, 0 );
if ( pos != text ) return value;
else return make_unexpected( "'"s + text + "' isn't a number" );
}
int main( int argc, char * argv[] )
{
auto text = argc > 1 ? argv[1] : "42";
auto ei = to_int( text );
if ( ei ) std::cout << "'" << text << "' is " << *ei << ", ";
else std::cout << "Error: " << ei.error();
}
```
### Compile and run
```
prompt> g++ -std=c++14 -Wall -I../include -o 01-basic.exe 01-basic.cpp && 01-basic.exe 123 && 01-basic.exe abc
'123' is 123, Error: 'abc' isn't a number
```
## In a nutshell
**expected lite** is a single-file header-only library to represent value objects that either contain a valid value or an error. The library is a partly implementation of the proposal for [std:&#58;expected](http://wg21.link/p0323) [1,2,3] for use with C++11 and later.
**Some Features and properties of expected lite** are ease of installation (single header), default and explicit construction of an expected, construction and assignment from a value that is convertible to the underlying type, copy- and move-construction and copy- and move-assignment from another expected of the same type, testing for the presence of a value, operators for unchecked access to the value or the error (pointer or reference), value() and value_or() for checked access to the value, relational operators, swap() and various factory functions.
*expected lite* shares the approach to in-place tags with [any-lite](https://github.com/martinmoene/any-lite), [optional-lite](https://github.com/martinmoene/optional-lite) and with [variant-lite](https://github.com/martinmoene/variant-lite) and these libraries can be used together.
**Not provided** are reference-type expecteds. *expected lite* doesn't honour triviality of value and error types. *expected lite* doesn't handle overloaded *address of* operators.
For more examples, see [1].
## License
*expected lite* is distributed under the [Boost Software License](https://github.com/martinmoene/XXXX-lite/blob/master/LICENSE.txt).
## Dependencies
*expected lite* has no other dependencies than the [C++ standard library](http://en.cppreference.com/w/cpp/header).
## Installation
*expected lite* is a single-file header-only library. Put `expected.hpp` directly into the project source tree or somewhere reachable from your project.
## Synopsis
**Contents**
- [Configuration](#configuration)
- [Types in namespace nonstd](#types-in-namespace-nonstd)
- [Interface of expected](#interface-of-expected)
- [Algorithms for expected](#algorithms-for-expected)
- [Interface of unexpected_type](#interface-of-unexpected_type)
- [Algorithms for unexpected_type](#algorithms-for-unexpected_type)
### Configuration
#### Tweak header
If the compiler supports [`__has_include()`](https://en.cppreference.com/w/cpp/preprocessor/include), *expected lite* supports the [tweak header](https://vector-of-bool.github.io/2020/10/04/lib-configuration.html) mechanism. Provide your *tweak header* as `nonstd/expected.tweak.hpp` in a folder in the include-search-path. In the tweak header, provide definitions as documented below, like `#define expected_CPLUSPLUS 201103L`.
#### Standard selection macro
\-D<b>nsel\_CPLUSPLUS</b>=199711L
Define this macro to override the auto-detection of the supported C++ standard, or if your compiler does not set the `__cplusplus` macro correctly.
#### Select `std::expected` or `nonstd::expected`
At default, *expected lite* uses `std::expected` if it is available and lets you use it via namespace `nonstd`. You can however override this default and explicitly request to use `std::expected` or expected lite's `nonstd::expected` as `nonstd::expected` via the following macros.
-D<b>nsel\_CONFIG\_SELECT\_EXPECTED</b>=nsel_EXPECTED_DEFAULT
Define this to `nsel_EXPECTED_STD` to select `std::expected` as `nonstd::expected`. Define this to `nsel_EXPECTED_NONSTD` to select `nonstd::expected` as `nonstd::expected`. Default is undefined, which has the same effect as defining to `nsel_EXPECTED_DEFAULT`.
-D<b>nsel\_P0323R</b>=7 *(default)*
Define this to the proposal revision number to control the presence and behavior of features (see tables). Default is 7 for the latest revision.
#### Disable C++ exceptions
-D<b>nsel\_CONFIG\_NO\_EXCEPTIONS</b>=0
Define this to 1 if you want to compile without exceptions. If not defined, the header tries and detect if exceptions have been disabled (e.g. via `-fno-exceptions` or `/kernel`). Default determined in header.
#### Enable SEH exceptions
-D<b>nsel\_CONFIG\_NO\_EXCEPTIONS\_SEH</b>=0
Define this to 1 or 0 to control the use of SEH when C++ exceptions are disabled (see above). If not defined, the header tries and detect if SEH is available if C++ exceptions have been disabled (e.g. via `-fno-exceptions` or `/kernel`). Default determined in header.
#### Enable compilation errors
\-D<b>nsel\_CONFIG\_CONFIRMS\_COMPILATION\_ERRORS</b>=0
Define this macro to 1 to experience the by-design compile-time errors of the library in the test suite. Default is 0.
### Types in namespace nonstd
| Purpose | Type | Note / Object |
|-----------------|------|---------------|
| Expected | template&lt;typename T, typename E = std::exception_ptr><br>class **expected**; | nsel_P0323 <= 2 |
| Expected | template&lt;typename T, typename E><br>class **expected**; | nsel_P0323 > 2 |
| Error type | template&lt;typename E><br>class **unexpected_type**; | &nbsp; |
| Error type | template&lt;><br>class **unexpected_type**&lt;std::exception_ptr>; | nsel_P0323 <= 2 |
| Error type | template&lt;typename E><br>class **unexpected**; | >= C++17 |
| Traits | template&lt;typename E><br>struct **is_unexpected**; | nsel_P0323 <= 3 |
| In-place value construction | struct **in_place_t**; | in_place_t in_place{}; |
| In-place error construction | struct **in_place_unexpected_t**; | in_place_unexpected_t<br>unexpect{}; |
| In-place error construction | struct **in_place_unexpected_t**; | in_place_unexpected_t<br>in_place_unexpected{}; |
| Error reporting | class **bad_expected_access**; |&nbsp; |
### Interface of expected
| Kind | Method | Result |
|--------------|-------------------------------------------------------------------------|--------|
| Construction | [constexpr] **expected**() noexcept(...) | an object with default value |
| &nbsp; | [constexpr] **expected**( expected const & other ) | initialize to contents of other |
| &nbsp; | [constexpr] **expected**( expected && other ) | move contents from other |
| &nbsp; | [constexpr] **expected**( value_type const & value ) | initialize to value |
| &nbsp; | [constexpr] **expected**( value_type && value ) noexcept(...) | move from value |
| &nbsp; | [constexpr] explicit **expected**( in_place_t, Args&&... args ) | construct value in-place from args |
| &nbsp; | [constexpr] explicit **expected**( in_place_t,<br>&emsp;std::initializer_list&lt;U> il, Args&&... args ) | construct value in-place from args |
| &nbsp; | [constexpr] **expected**( unexpected_type<E> const & error ) | initialize to error |
| &nbsp; | [constexpr] **expected**( unexpected_type<E> && error ) | move from error |
| &nbsp; | [constexpr] explicit **expected**( in_place_unexpected_t,<br>&emsp;Args&&... args ) | construct error in-place from args |
| &nbsp; | [constexpr] explicit **expected**( in_place_unexpected_t,<br>&emsp;std::initializer_list&lt;U> il, Args&&... args )| construct error in-place from args |
| Destruction | ~**expected**() | destruct current content |
| Assignment | expected **operator=**( expected const & other ) | assign contents of other;<br>destruct current content, if any |
| &nbsp; | expected & **operator=**( expected && other ) noexcept(...) | move contents of other |
| &nbsp; | expected & **operator=**( U && v ) | move value from v |
| &nbsp; | expected & **operator=**( unexpected_type<E> const & u ) | initialize to unexpected |
| &nbsp; | expected & **operator=**( unexpected_type<E> && u ) | move from unexpected |
| &nbsp; | template&lt;typename... Args><br>void **emplace**( Args &&... args ) | emplace from args |
| &nbsp; | template&lt;typename U, typename... Args><br>void **emplace**( std::initializer_list&lt;U> il, Args &&... args ) | emplace from args |
| Swap | void **swap**( expected & other ) noexcept | swap with other |
| Observers | constexpr value_type const \* **operator->**() const | pointer to current content (const);<br>must contain value |
| &nbsp; | value_type \* **operator->**() | pointer to current content (non-const);<br>must contain value |
| &nbsp; | constexpr value_type const & **operator \***() const & | the current content (const ref);<br>must contain value |
| &nbsp; | constexpr value_type && **operator \***() && | the current content (non-const ref);<br>must contain value |
| &nbsp; | constexpr explicit operator **bool**() const noexcept | true if contains value |
| &nbsp; | constexpr **has_value**() const noexcept | true if contains value |
| &nbsp; | constexpr value_type const & **value**() const & | current content (const ref);<br>see [note 1](#note1) |
| &nbsp; | value_type & **value**() & | current content (non-const ref);<br>see [note 1](#note1) |
| &nbsp; | constexpr value_type && **value**() && | move from current content;<br>see [note 1](#note1) |
| &nbsp; | constexpr error_type const & **error**() const & | current error (const ref);<br>must contain error |
| &nbsp; | error_type & **error**() & | current error (non-const ref);<br>must contain error |
| &nbsp; | constexpr error_type && **error**() && | move from current error;<br>must contain error |
| &nbsp; | constexpr unexpected_type<E> **get_unexpected**() const | the error as unexpected&lt;>;<br>must contain error |
| &nbsp; | template&lt;typename Ex><br>bool **has_exception**() const | true of contains exception (as base) |
| &nbsp; | value_type **value_or**( U && v ) const & | value or move from v |
| &nbsp; | value_type **value_or**( U && v ) && | move from value or move from v |
| &nbsp; | ... | &nbsp; |
<a id="note1"></a>Note 1: checked access: if no content, for std::exception_ptr rethrows error(), otherwise throws bad_expected_access(error()).
### Algorithms for expected
| Kind | Function |
|---------------------------------|----------|
| Comparison with expected | &nbsp; |
| ==&ensp;!= | template&lt;typename T1, typename E1, typename T2, typename E2><br>constexpr bool operator ***op***(<br>&emsp;expected&lt;T1,E1> const & x,<br>&emsp;expected&lt;T2,E2> const & y ) |
| Comparison with expected | nsel_P0323R <= 2 |
| <&ensp;>&ensp;<=&ensp;>= | template&lt;typename T, typename E><br>constexpr bool operator ***op***(<br>&emsp;expected&lt;T,E> const & x,<br>&emsp;expected&lt;T,E> const & y ) |
| Comparison with unexpected_type | &nbsp; |
| ==&ensp;!= | template&lt;typename T1, typename E1, typename E2><br>constexpr bool operator ***op***(<br>&emsp;expected&lt;T1,E1> const & x,<br>&emsp;unexpected_type&lt;E2> const & u ) |
| &nbsp; | template&lt;typename T1, typename E1, typename E2><br>constexpr bool operator ***op***(<br>&emsp;unexpected_type&lt;E2> const & u,<br>&emsp;expected&lt;T1,E1> const & x ) |
| Comparison with unexpected_type | nsel_P0323R <= 2 |
| <&ensp;>&ensp;<=&ensp;>= | template&lt;typename T, typename E><br>constexpr bool operator ***op***(<br>&emsp;expected&lt;T,E> const & x,<br>&emsp;unexpected_type&lt;E> const & u ) |
| &nbsp; | template&lt;typename T, typename E><br>constexpr bool operator ***op***(<br>&emsp;unexpected_type&lt;E> const & u,<br>&emsp;expected&lt;T,E> const & x ) |
| Comparison with T | &nbsp; |
| ==&ensp;!= | template&lt;typename T, typename E><br>constexpr bool operator ***op***(<br>&emsp;expected&lt;T,E> const & x,<br>&emsp;T const & v ) |
| &nbsp; | template&lt;typename T, typename E><br>constexpr bool operator ***op***(<br>&emsp;T const & v,<br>&emsp;expected&lt;T,E> const & x ) |
| Comparison with T | nsel_P0323R <= 2 |
| <&ensp;>&ensp;<=&ensp;>= | template&lt;typename T, typename E><br>constexpr bool operator ***op***(<br>&emsp;expected&lt;T,E> const & x,<br>&emsp;T const & v ) |
| &nbsp; | template&lt;typename T, typename E><br>constexpr bool operator ***op***(<br>&emsp;T const & v,<br>&emsp;expected&lt;T,E> const & x ) |
| Specialized algorithms | &nbsp; |
| Swap | template&lt;typename T, typename E><br>void **swap**(<br>&emsp;expected&lt;T,E> & x,<br>&emsp;expected&lt;T,E> & y )&emsp;noexcept( noexcept( x.swap(y) ) ) |
| Make expected from | nsel_P0323R <= 3 |
| &emsp;Value | template&lt;typename T><br>constexpr auto **make_expected**( T && v ) -><br>&emsp;expected< typename std::decay&lt;T>::type> |
| &emsp;Nothing | auto **make_expected**() -> expected&lt;void> |
| &emsp;Current exception | template&lt;typename T><br>constexpr auto **make_expected_from_current_exception**() -> expected&lt;T> |
| &emsp;Exception | template&lt;typename T><br>auto **make_expected_from_exception**( std::exception_ptr v ) -> expected&lt;T>|
| &emsp;Error | template&lt;typename T, typename E><br>constexpr auto **make_expected_from_error**( E e ) -><br>&emsp;expected&lt;T, typename std::decay&lt;E>::type> |
| &emsp;Call | template&lt;typename F><br>auto **make_expected_from_call**( F f ) -><br>&emsp;expected< typename std::result_of&lt;F()>::type>|
| &emsp;Call, void specialization | template&lt;typename F><br>auto **make_expected_from_call**( F f ) -> expected&lt;void> |
### Interface of unexpected_type
| Kind | Method | Result |
|--------------|-----------------------------------------------------------|--------|
| Construction | **unexpected_type**() = delete; | no default construction |
| &nbsp; | constexpr explicit **unexpected_type**( E const & error ) | copy-constructed from an E |
| &nbsp; | constexpr explicit **unexpected_type**( E && error ) | move-constructed from an E |
| Observers | constexpr error_type const & **value**() const | can observe contained error |
| &nbsp; | error_type & **value**() | can modify contained error |
### Algorithms for unexpected_type
| Kind | Function |
|-------------------------------|----------|
| Comparison with unexpected | &nbsp; |
| ==&ensp;!= | template&lt;typename E><br>constexpr bool operator ***op***(<br>&emsp;unexpected_type&lt;E> const & x,<br>&emsp;unexpected_type&lt;E> const & y ) |
| Comparison with unexpected | nsel_P0323R <= 2 |
| <&ensp;>&ensp;<=&ensp;>= | template&lt;typename E><br>constexpr bool operator ***op***(<br>&emsp;unexpected_type&lt;E> const & x,<br>&emsp;unexpected_type&lt;E> const & y ) |
| Comparison with exception_ptr | &nbsp; |
| ==&ensp;!= | constexpr bool operator ***op***(<br>&emsp;unexpected_type&lt;std::exception_ptr> const & x,<br>&emsp;unexpected_type&lt;std::exception_ptr> const & y ) |
| Comparison with exception_ptr | nsel_P0323R <= 2 |
| <&ensp;>&ensp;<=&ensp;>= | constexpr bool operator ***op***(<br>&emsp;unexpected_type&lt;std::exception_ptr> const & x,<br>&emsp;unexpected_type&lt;std::exception_ptr> const & y ) |
| Specialized algorithms | &nbsp; |
| Make unexpected from | &nbsp; |
| &emsp;Error | template&lt;typename E><br>[constexpr] auto **make_unexpected**( E && v) -><br>&emsp;unexpected_type< typename std::decay&lt;E>::type>|
| Make unexpected from | nsel_P0323R <= 3 |
| &emsp;Current exception | [constexpr] auto **make_unexpected_from_current_exception**() -><br>&emsp;unexpected_type< std::exception_ptr>|
<a id="comparison"></a>
## Comparison with like types
|Feature |<br>std::pair|std:: optional |std:: expected |nonstd:: expected |Boost. Expected |Nonco expected |Andrei Expected |Hagan required |
|----------------------|-------------|---------------|---------------|------------------|----------------|---------------|----------------|---------------|
|More information | see [14] | see [5] | see [1] | this work | see [4] | see [7] | see [8] | see [13] |
| | | | | | | | | |
| C++03 | yes | no | no | no/not yet | no (union) | no | no | yes |
| C++11 | yes | no | no | yes | yes | yes | yes | yes |
| C++14 | yes | no | no | yes | yes | yes | yes | yes |
| C++17 | yes | yes | no | yes | yes | yes | yes | yes |
| | | | | | | | | |
|DefaultConstructible | T param | yes | yes | yes | yes | no | no | no |
|In-place construction | no | yes | yes | yes | yes | yes | no | no |
|Literal type | yes | yes | yes | yes | yes | no | no | no |
| | | | | | | | | |
|Disengaged information| possible | no | yes | yes | yes | yes | yes | no |
|Vary disengaged type | yes | no | yes | yes | yes | no | no | no |
|Engaged nonuse throws | no | no | no | no | error_traits | no | no | yes |
|Disengaged use throws | no | yes, value() | yes, value() | yes, value() | yes,<br>value()| yes,<br>get() | yes,<br>get() | n/a |
| | | | | | | | | |
|Proxy (rel.ops) | no | yes | yes | yes | yes | no | no | no |
|References | no | yes | no/not yet | no/not yet | no/not yet | yes | no | no |
|Chained visitor(s) | no | no | yes | maybe | yes | no | no | no |
Note 1: std:&#58;*experimental*:&#58;expected
Note 2: sources for [Nonco expected](https://github.com/martinmoene/spike-expected/tree/master/nonco), [Andrei Expected](https://github.com/martinmoene/spike-expected/tree/master/alexandrescu) and [Hagan required](https://github.com/martinmoene/spike-expected/tree/master/hagan) can befound in the [spike-expected](https://github.com/martinmoene/spike-expected) repository.
## Reported to work with
TBD
## Implementation notes
TBD
## Other implementations of expected
- Simon Brand. [C++11/14/17 std::expected with functional-style extensions](https://github.com/TartanLlama/expected). Single-header.
- Isabella Muerte. [MNMLSTC Core](https://github.com/mnmlstc/core) (C++11).
- Vicente J. Botet Escriba. [stdmake's expected](https://github.com/viboes/std-make/tree/master/include/experimental/fundamental/v3/expected) (C++17).
- Facebook. [ Folly's Expected.h](https://github.com/facebook/folly/blob/master/folly/Expected.h) (C++14).
## Notes and references
[1] Vicente J. Botet Escriba. [p0323 - A proposal to add a utility class to represent expected object (latest)](http://wg21.link/p0323) (HTML). ([r10](http://wg21.link/p0323r10), [r9](http://wg21.link/p0323r9), [r8](http://wg21.link/p0323r8), [r7](http://wg21.link/p0323r7), [r6](http://wg21.link/p0323r6), [r5](http://wg21.link/p0323r5), [r4](http://wg21.link/p0323r4), [r3](http://wg21.link/p0323r3), [r2](http://wg21.link/p0323r2), [r1](http://wg21.link/n4109), [r0](http://wg21.link/n4015), [draft](https://github.com/viboes/std-make/blob/master/doc/proposal/expected/DXXXXR0_expected.pdf)).
[2] Vicente J. Botet Escriba. [JASEL: Just a simple experimental library for C++](https://github.com/viboes/std-make). Reference implementation of [expected](https://github.com/viboes/std-make/tree/master/include/experimental/fundamental/v3/expected).
[3] Vicente J. Botet Escriba. [Expected - An exception-friendly Error Monad](https://www.youtube.com/watch?v=Zdlt1rgYdMQ). C++Now 2014. 24 September 2014.
[4] Pierre Talbot. [Boost.Expected. Unofficial Boost candidate](http://www.google-melange.com/gsoc/proposal/review/google/gsoc2013/trademark/25002). 5 May 2013. [GitHub](https://github.com/TrademarkPewPew/Boost.Expected), [GSoC 2013 Proposal](http://www.google-melange.com/gsoc/proposal/review/google/gsoc2013/trademark/25002), [boost@lists.boost.org](http://permalink.gmane.org/gmane.comp.lib.boost.devel/240056 ).
[5] Fernando Cacciola and Andrzej Krzemieński. [A proposal to add a utility class to represent optional objects (Revision 4)](http://isocpp.org/files/papers/N3672.html). ISO/IEC JTC1 SC22 WG21 N3672 2013-04-19.
[6] Andrzej Krzemieński, [Optional library implementation in C++11](https://github.com/akrzemi1/Optional/).
[7] Anto Nonco. [Extending expected<T> to deal with references](http://anto-nonco.blogspot.nl/2013/03/extending-expected-to-deal-with.html). 27 May 2013.
[8] Andrei Alexandrescu. Systematic Error Handling in C++. Prepared for The C++and Beyond Seminar 2012. [Video](http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C). [Slides](http://sdrv.ms/RXjNPR).
[9] Andrei Alexandrescu. [Choose your Poison: Exceptions or Error Codes? (PDF)](http://accu.org/content/conf2007/Alexandrescu-Choose_Your_Poison.pdf). ACCU Conference 2007.
[10] Andrei Alexandrescu. [The Power of None (PPT)](http://nwcpp.org/static/talks/2006/The_Power_of_None.ppt). Northwest C++ Users' Group. [May 17th, 2006](http://nwcpp.org/may-2006.html).
[11] Jon Jagger. [A Return Type That Doesn't Like Being Ignored](http://accu.org/var/uploads/journals/overload53-FINAL.pdf#page=18). Overload issue 53, February 2003.
[12] Andrei Alexandrescu. [Error Handling in C++: Are we inching towards a total solution?](http://accu.org/index.php/conferences/2002/speakers2002). ACCU Conference 2002.
[13] Ken Hagan et al. [Exploding return codes](https://groups.google.com/d/msg/comp.lang.c++.moderated/BkZqPfoq3ys/H_PMR8Sat4oJ). comp.lang.c++.moderated. 11 February 2000.
[14] [std::pair](http://en.cppreference.com/w/cpp/utility/pair). cppreference.com
[15] Niall Douglas. [Outcome](https://ned14.github.io/outcome/). Very lightweight outcome&lt;T> and result&lt;T> (non-Boost edition).
[16] Niall Douglas. [p0762 - Concerns about expected&lt;T, E> from the Boost.Outcome peer review](http://wg21.link/p0762). 15 October 2017.
## Appendix
### A.1 Compile-time information
The version of *expected lite* is available via tag `[.version]`. The following tags are available for information on the compiler and on the C++ standard library used: `[.compiler]`, `[.stdc++]`, `[.stdlanguage]` and `[.stdlibrary]`.
### A.2 Expected lite test specification
<details>
<summary>click to expand</summary>
<p>
```Text
unexpected_type: Disallows default construction
unexpected_type: Allows to copy-construct from unexpected_type, default
unexpected_type: Allows to move-construct from unexpected_type, default
unexpected_type: Allows to in-place-construct
unexpected_type: Allows to in-place-construct from initializer_list
unexpected_type: Allows to copy-construct from error_type
unexpected_type: Allows to move-construct from error_type
unexpected_type: Allows to copy-construct from unexpected_type, explicit converting
unexpected_type: Allows to copy-construct from unexpected_type, non-explicit converting
unexpected_type: Allows to move-construct from unexpected_type, explicit converting
unexpected_type: Allows to move-construct from unexpected_type, non-explicit converting
unexpected_type: Allows to copy-assign from unexpected_type, default
unexpected_type: Allows to move-assign from unexpected_type, default
unexpected_type: Allows to copy-assign from unexpected_type, converting
unexpected_type: Allows to move-assign from unexpected, converting
unexpected_type: Allows to observe its value via a l-value reference
unexpected_type: Allows to observe its value via a r-value reference
unexpected_type: Allows to modify its value via a l-value reference
unexpected_type: Allows to be swapped
unexpected_type<std::exception_ptr>: Disallows default construction
unexpected_type<std::exception_ptr>: Allows to copy-construct from error_type
unexpected_type<std::exception_ptr>: Allows to move-construct from error_type
unexpected_type<std::exception_ptr>: Allows to copy-construct from an exception
unexpected_type<std::exception_ptr>: Allows to observe its value
unexpected_type<std::exception_ptr>: Allows to modify its value
unexpected_type: Provides relational operators
unexpected_type: Provides relational operators, std::exception_ptr specialization
make_unexpected(): Allows to create an unexpected_type<E> from an E
unexpected: C++17 and later provide unexpected_type as unexpected
bad_expected_access: Disallows default construction
bad_expected_access: Allows construction from error_type
bad_expected_access: Allows to observe its error
bad_expected_access: Allows to change its error
bad_expected_access: Provides non-empty what()
expected: Allows to default construct
expected: Allows to copy-construct from expected: value
expected: Allows to copy-construct from expected: error
expected: Allows to move-construct from expected: value
expected: Allows to move-construct from expected: error
expected: Allows to copy-construct from expected; value, explicit converting
expected: Allows to copy-construct from expected; error, explicit converting
expected: Allows to copy-construct from expected; value, non-explicit converting
expected: Allows to copy-construct from expected; error, non-explicit converting
expected: Allows to move-construct from expected; value, explicit converting
expected: Allows to move-construct from expected; error, explicit converting
expected: Allows to move-construct from expected; value, non-explicit converting
expected: Allows to move-construct from expected; error, non-explicit converting
expected: Allows to forward-construct from value, explicit converting
expected: Allows to forward-construct from value, non-explicit converting
expected: Allows to in-place-construct value
expected: Allows to in-place-construct value from initializer_list
expected: Allows to copy-construct from unexpected, explicit converting
expected: Allows to copy-construct from unexpected, non-explicit converting
expected: Allows to move-construct from unexpected, explicit converting
expected: Allows to move-construct from unexpected, non-explicit converting
expected: Allows to in-place-construct error
expected: Allows to in-place-construct error from initializer_list
expected: Allows to copy-assign from expected, value
expected: Allows to copy-assign from expected, error
expected: Allows to move-assign from expected, value
expected: Allows to move-assign from expected, error
expected: Allows to forward-assign from value
expected: Allows to copy-assign from unexpected
expected: Allows to move-assign from unexpected
expected: Allows to move-assign from move-only unexpected
expected: Allows to emplace value
expected: Allows to emplace value from initializer_list
expected: Allows to be swapped
expected: Allows to observe its value via a pointer
expected: Allows to observe its value via a pointer to constant
expected: Allows to modify its value via a pointer
expected: Allows to observe its value via a l-value reference
expected: Allows to observe its value via a r-value reference
expected: Allows to modify its value via a l-value reference
expected: Allows to modify its value via a r-value reference
expected: Allows to observe if it contains a value (or error)
expected: Allows to observe its value
expected: Allows to modify its value
expected: Allows to move its value
expected: Allows to observe its error
expected: Allows to modify its error
expected: Allows to move its error
expected: Allows to observe its error as unexpected
expected: Allows to query if it contains an exception of a specific base type
expected: Allows to observe its value if available, or obtain a specified value otherwise
expected: Allows to move its value if available, or obtain a specified value otherwise
expected: Throws bad_expected_access on value access when disengaged
expected<void>: Allows to default-construct
expected<void>: Allows to copy-construct from expected<void>: value
expected<void>: Allows to copy-construct from expected<void>: error
expected<void>: Allows to move-construct from expected<void>: value
expected<void>: Allows to move-construct from expected<void>: error
expected<void>: Allows to in-place-construct
expected<void>: Allows to copy-construct from unexpected, explicit converting
expected<void>: Allows to copy-construct from unexpected, non-explicit converting
expected<void>: Allows to move-construct from unexpected, explicit converting
expected<void>: Allows to move-construct from unexpected, non-explicit converting
expected<void>: Allows to in-place-construct unexpected_type
expected<void>: Allows to in-place-construct error from initializer_list
expected<void>: Allows to copy-assign from expected, value
expected<void>: Allows to copy-assign from expected, error
expected<void>: Allows to move-assign from expected, value
expected<void>: Allows to move-assign from expected, error
expected<void>: Allows to emplace value
expected<void>: Allows to be swapped
expected<void>: Allows to observe if it contains a value (or error)
expected<void>: Allows to observe its value
expected<void>: Allows to observe its error
expected<void>: Allows to modify its error
expected<void>: Allows to move its error
expected<void>: Allows to observe its error as unexpected
expected<void>: Allows to query if it contains an exception of a specific base type
expected<void>: Throws bad_expected_access on value access when disengaged
operators: Provides expected relational operators
swap: Allows expected to be swapped
std::hash: Allows to compute hash value for expected
tweak header: reads tweak header if supported [tweak]
```
</p>
</details>

View File

@@ -0,0 +1,71 @@
version: "{branch} #{build}"
shallow_clone: true
image:
- Visual Studio 2019
- Visual Studio 2017
- Visual Studio 2015
platform:
- Win32
- x64
configuration:
- Debug
- Release
build:
parallel: true
environment:
matrix:
- generator: "Visual Studio 16 2019"
select_sv: -DEXPECTED_LITE_OPT_SELECT_STD=ON
- generator: "Visual Studio 16 2019"
select_sv: -DEXPECTED_LITE_OPT_SELECT_NONSTD=ON
- generator: "Visual Studio 15 2017"
select_sv: -DEXPECTED_LITE_OPT_SELECT_STD=ON
- generator: "Visual Studio 15 2017"
select_sv: -DEXPECTED_LITE_OPT_SELECT_NONSTD=ON
- generator: "Visual Studio 14 2015"
# - generator: "Visual Studio 12 2013"
# - generator: "Visual Studio 11 2012"
# - generator: "Visual Studio 10 2010"
matrix:
exclude:
- image: Visual Studio 2015
generator: "Visual Studio 16 2019"
- image: Visual Studio 2019
generator: "Visual Studio 15 2017"
- image: Visual Studio 2019
generator: "Visual Studio 14 2015"
- image: Visual Studio 2019
generator: "Visual Studio 12 2013"
- image: Visual Studio 2019
generator: "Visual Studio 11 2012"
- image: Visual Studio 2019
generator: "Visual Studio 10 2010"
- image: Visual Studio 2015
generator: "Visual Studio 15 2017"
- image: Visual Studio 2017
generator: "Visual Studio 16 2019"
- image: Visual Studio 2017
generator: "Visual Studio 14 2015"
- image: Visual Studio 2017
generator: "Visual Studio 12 2013"
- image: Visual Studio 2017
generator: "Visual Studio 11 2012"
- image: Visual Studio 2017
generator: "Visual Studio 10 2010"
before_build:
- mkdir build && cd build
- cmake -A %platform% -G "%generator%" "%select_sv%" -DEXPECTED_LITE_OPT_BUILD_TESTS=ON -DEXPECTED_LITE_OPT_BUILD_EXAMPLES=OFF ..
build_script:
- cmake --build . --config %configuration%
test_script:
- ctest --output-on-failure -C %configuration%

View File

@@ -0,0 +1,24 @@
# Adapted from write_basic_package_version_file(... COMPATIBILITY SameMajorVersion) output
# ARCH_INDEPENDENT is only present in cmake 3.14 and onwards
set( PACKAGE_VERSION "@package_version@" )
if( PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION )
set( PACKAGE_VERSION_COMPATIBLE FALSE )
else()
if( "@package_version@" MATCHES "^([0-9]+)\\." )
set( CVF_VERSION_MAJOR "${CMAKE_MATCH_1}" )
else()
set( CVF_VERSION_MAJOR "@package_version@" )
endif()
if( PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR )
set( PACKAGE_VERSION_COMPATIBLE TRUE )
else()
set( PACKAGE_VERSION_COMPATIBLE FALSE )
endif()
if( PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION )
set( PACKAGE_VERSION_EXACT TRUE )
endif()
endif()

View File

@@ -0,0 +1,7 @@
@PACKAGE_INIT@
# Only include targets once:
if( NOT TARGET @package_name@::@package_name@ )
include( "${CMAKE_CURRENT_LIST_DIR}/@package_target@.cmake" )
endif()

View File

@@ -0,0 +1,27 @@
from conans import ConanFile, CMake
class ExpectedLiteConan(ConanFile):
version = "0.6.2"
name = "expected-lite"
description = "Expected objects for C++11 and later"
license = "Boost Software License - Version 1.0. http://www.boost.org/LICENSE_1_0.txt"
url = "https://github.com/martinmoene/expected-lite.git"
exports_sources = "include/nonstd/*", "CMakeLists.txt", "cmake/*", "LICENSE.txt"
settings = "compiler", "build_type", "arch"
build_policy = "missing"
author = "Martin Moene"
def build(self):
"""Avoid warning on build step"""
pass
def package(self):
"""Run CMake install"""
cmake = CMake(self)
cmake.definitions["EXPECTED_LITE_OPT_BUILD_TESTS"] = "OFF"
cmake.definitions["EXPECTED_LITE_OPT_BUILD_EXAMPLES"] = "OFF"
cmake.configure()
cmake.install()
def package_info(self):
self.info.header_only()

View File

@@ -0,0 +1,33 @@
// Convert text to number and yield expected with number or error text.
#include "nonstd/expected.hpp"
#include <cstdlib>
#include <iostream>
#include <string>
using namespace nonstd;
using namespace std::literals;
auto to_int( char const * const text ) -> expected<int, std::string>
{
char * pos = nullptr;
auto value = strtol( text, &pos, 0 );
if ( pos != text ) return value;
else return make_unexpected( "'"s + text + "' isn't a number" );
}
int main( int argc, char * argv[] )
{
auto text = argc > 1 ? argv[1] : "42";
auto ei = to_int( text );
if ( ei ) std::cout << "'" << text << "' is " << *ei << ", ";
else std::cout << "Error: " << ei.error();
}
// cl -EHsc -wd4814 -I../include 01-basic.cpp && 01-basic.exe 123 && 01-basic.exe abc
// g++ -std=c++14 -Wall -I../include -o 01-basic.exe 01-basic.cpp && 01-basic.exe 123 && 01-basic.exe abc
// '123' is 123, Error: 'abc' isn't a number

View File

@@ -0,0 +1,68 @@
// Use a non-ignorable value with expected.
#include "nonstd/expected.hpp"
#include <iostream>
using namespace nonstd;
template< typename T >
class required
{
public:
required( T const & value)
: content( value ) {}
required( required && other )
: content( other.content )
, ignored( other.ignored )
{
other.ignored = false;
}
required( required const & other ) = delete;
~required() noexcept( false )
{
if ( ignored )
throw std::runtime_error("required: content unobserved");
};
T const & operator *() const { ignored = false; return content; }
private:
T content;
mutable bool ignored = true;
};
template< typename T >
auto make_required( T value ) -> required<T>
{
return required<T>( std::move(value) );
}
using unused_type = char;
auto produce( int value ) -> expected< required<int>, unused_type >
{
return make_required( std::move(value) );
}
int main( int argc, char * argv[] )
{
try
{
auto er42 = produce( 42 );
auto er13 = produce( 13 );
std::cout << "value: " << **er42 << "\n";
}
catch ( std::exception const & e )
{
std::cout << "Error: " << e.what();
}
}
// cl -EHsc -wd4814 -Zc:implicitNoexcept- -I../include 02-required.cpp && 02-required.exe
// g++ -std=c++14 -Wall -I../include -o 02-required.exe 02-required.cpp && 02-required.exe
// value: 42
// Error: required: content unobserved

View File

@@ -0,0 +1,77 @@
// Copyright (c) 2016-2020 Martin Moene
//
// https://github.com/martinmoene/expected-lite
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "nonstd/expected.hpp"
#include <iostream>
template< typename T >
void use( T const & /*x*/) {}
#define expected_PRESENT( x ) \
std::cout << #x << ": " << x << "\n"
#define expected_ABSENT( x ) \
std::cout << #x << ": (undefined)\n"
void report()
{
#ifdef __cpp_exceptions
expected_PRESENT( __cpp_exceptions );
#else
expected_ABSENT( __cpp_exceptions );
#endif
#ifdef __EXCEPTIONS
expected_PRESENT( __EXCEPTIONS );
#else
expected_ABSENT( __EXCEPTIONS );
#endif
#ifdef _HAS_EXCEPTIONS
expected_PRESENT( _HAS_EXCEPTIONS );
#else
expected_ABSENT( _HAS_EXCEPTIONS );
#endif
#ifdef _CPPUNWIND
expected_PRESENT( _CPPUNWIND );
#else
expected_ABSENT( _CPPUNWIND );
#endif
}
int violate_access()
{
nonstd::expected<int, char> eu( nonstd:: make_unexpected('a') );
return eu.value();
}
int main()
{
report();
#if ! nsel_CONFIG_NO_EXCEPTIONS_SEH
return violate_access();
#else
__try
{
return violate_access();
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
std::cerr << "\n*** Executing SEH __except block ***\n";
}
#endif
}
// -Dnsel_CONFIG_NO_EXCEPTIONS=1 automatically determined in expected.hpp
// -Dnsel_CONFIG_NO_EXCEPTIONS_SEH=0 default:1 for msvc
// cl -nologo -kernel -EHs-c- -GR- -I../include 03-no-exceptions.cpp && 03-no-exceptions
// cl -nologo -kernel -EHs-c- -GR- -Dnsel_CONFIG_NO_EXCEPTIONS_SEH=0 -I../include 03-no-exceptions.cpp && 03-no-exceptions
// g++ -Wall -fno-exceptions -I../include -o 03-no-exceptions 03-no-exceptions.cpp && 03-no-exceptions

View File

@@ -0,0 +1,79 @@
# Copyright (c) 2016-2022 Martin Moene.
#
# https://github.com/martinmoene/expected-lite
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
if( NOT DEFINED CMAKE_MINIMUM_REQUIRED_VERSION )
cmake_minimum_required( VERSION 3.8 FATAL_ERROR )
endif()
project( example LANGUAGES CXX )
set( unit_name "expected" )
set( PACKAGE ${unit_name}-lite )
message( STATUS "Subproject '${PROJECT_NAME}', various examples")
# Target default options and definitions:
set( OPTIONS "" )
#set( DEFINITIONS "" )
# Sources (.cpp), normal and no-exception, and their base names:
set( SOURCES_CPP11
02-required.cpp
)
set( SOURCES_CPP14
01-basic.cpp
)
# note: here variable must be quoted to create semicolon separated list:
string( REPLACE ".cpp" "" BASENAMES_CPP11 "${SOURCES_CPP11}" )
string( REPLACE ".cpp" "" BASENAMES_CPP14 "${SOURCES_CPP14}" )
set( TARGETS_CPP11 ${BASENAMES_CPP11} )
set( TARGETS_CPP14 ${BASENAMES_CPP14} )
set( TARGETS_ALL ${TARGETS_CPP11} ${TARGETS_CPP14} )
# add targets:
foreach( name ${TARGETS_ALL} )
add_executable( ${name} ${name}.cpp )
target_link_libraries( ${name} PRIVATE ${PACKAGE} )
endforeach()
# set compiler options:
if( ${CMAKE_GENERATOR} MATCHES Visual )
foreach( name ${TARGETS_ALL} )
target_compile_options( ${name} PUBLIC -W3 -EHsc -wd4814 -Zc:implicitNoexcept- )
endforeach()
else()
foreach( name ${TARGETS_ALL} )
target_compile_options( ${name} PUBLIC -Wall )
endforeach()
foreach( name ${TARGETS_CPP11} )
target_compile_options( ${name} PUBLIC -std=c++11 )
endforeach()
foreach( name ${TARGETS_CPP14} )
target_compile_options( ${name} PUBLIC -std=c++14 )
endforeach()
endif()
# configure unit tests via CTest:
enable_testing()
foreach( name ${TARGETS_ALL} )
add_test ( NAME ${name} COMMAND ${name} )
set_property( TEST ${name} PROPERTY LABELS example )
endforeach()
# end of file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="Expected Lite" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Release">
<Option output="bin/Release/optional3" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
</Compiler>
<Unit filename="../../.gitattributes" />
<Unit filename="../../.gitignore" />
<Unit filename="../../.travis.yml" />
<Unit filename="../../CHANGES.txt" />
<Unit filename="../../CMakeLists.txt" />
<Unit filename="../../LICENSE.txt" />
<Unit filename="../../Notes.md" />
<Unit filename="../../README.md" />
<Unit filename="../../appveyor.yml" />
<Unit filename="../../cmake/expected-lite-config-version.cmake.in" />
<Unit filename="../../cmake/expected-lite-config.cmake.in" />
<Unit filename="../../conanfile.py" />
<Unit filename="../../example/01-basic.cpp" />
<Unit filename="../../example/02-required.cpp" />
<Unit filename="../../example/CMakeLists.txt" />
<Unit filename="../../include/nonstd/expected.hpp" />
<Unit filename="../../script/create-cov-rpt.py" />
<Unit filename="../../script/create-vcpkg.py" />
<Unit filename="../../script/update-version.py" />
<Unit filename="../../script/upload-conan.py" />
<Unit filename="../../test/CMakeLists.txt" />
<Unit filename="../../test/expected-main.t.cpp" />
<Unit filename="../../test/expected-main.t.hpp" />
<Unit filename="../../test/expected.t.cpp" />
<Unit filename="../../test/lest.hpp" />
<Unit filename="../../test/odr.cpp" />
<Unit filename="../../test/t-odr.bat" />
<Unit filename="../../test/t.bat" />
<Unit filename="../../test/tc.bat" />
<Unit filename="../../test/tg-all.bat" />
<Unit filename="../../test/tg.bat" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_workspace_file>
<Workspace title="Workspace">
<Project filename="expected.cbp" />
<Project filename="../../optional-lite/project/optional.cbp" />
<Project filename="../../expected-spike/codeblocks.cbp" />
<Project filename="../../../GitHub-Pre/IsoCpp/gsl-lite/project/gsl-lite.cbp" />
</Workspace>
</CodeBlocks_workspace_file>

View File

@@ -0,0 +1,114 @@
#!/usr/bin/env python
#
# Copyright 2019-2019 by Martin Moene
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# script/create-cov-rpt.py, Python 3.4 and later
#
import argparse
import os
import re
import sys
import subprocess
# Configuration:
cfg_github_project = 'expected-lite'
cfg_github_user = 'martinmoene'
cfg_prj_folder_level = 3
tpl_coverage_cmd = 'opencppcoverage --no_aggregate_by_file --sources {src} -- {exe}'
# End configuration.
def project_folder( f, args ):
"""Project root"""
if args.prj_folder:
return args.prj_folder
return os.path.normpath( os.path.join( os.path.dirname( os.path.abspath(f) ), '../' * args.prj_folder_level ) )
def executable_folder( f ):
"""Folder where the xecutable is"""
return os.path.dirname( os.path.abspath(f) )
def executable_name( f ):
"""Folder where the executable is"""
return os.path.basename( f )
def createCoverageReport( f, args ):
print( "Creating coverage report for project '{usr}/{prj}', '{file}':".
format( usr=args.user, prj=args.project, file=f ) )
cmd = tpl_coverage_cmd.format( folder=executable_folder(f), src=project_folder(f, args), exe=executable_name(f) )
if args.verbose:
print( "> {}".format(cmd) )
if not args.dry_run:
os.chdir( executable_folder(f) )
subprocess.call( cmd, shell=False )
os.chdir( project_folder(f, args) )
def createCoverageReports( args ):
for f in args.executable:
createCoverageReport( f, args )
def createCoverageReportFromCommandLine():
"""Collect arguments from the commandline and create coverage report."""
parser = argparse.ArgumentParser(
description='Create coverage report.',
epilog="""""",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'executable',
metavar='executable',
type=str,
nargs=1,
help='executable to report on')
parser.add_argument(
'-n', '--dry-run',
action='store_true',
help='do not execute conan commands')
parser.add_argument(
'-v', '--verbose',
action='count',
default=0,
help='level of progress reporting')
parser.add_argument(
'--user',
metavar='u',
type=str,
default=cfg_github_user,
help='github user name')
parser.add_argument(
'--project',
metavar='p',
type=str,
default=cfg_github_project,
help='github project name')
parser.add_argument(
'--prj-folder',
metavar='f',
type=str,
default=None,
help='project root folder')
parser.add_argument(
'--prj-folder-level',
metavar='n',
type=int,
default=cfg_prj_folder_level,
help='project root folder level from executable')
createCoverageReports( parser.parse_args() )
if __name__ == '__main__':
createCoverageReportFromCommandLine()
# end of file

View File

@@ -0,0 +1,223 @@
#!/usr/bin/env python
#
# Copyright 2019-2019 by Martin Moene
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# script/upload-conan.py, Python 3.4 and later
#
import argparse
import os
import re
import sys
import subprocess
# Configuration:
cfg_github_project = 'expected-lite'
cfg_github_user = 'martinmoene'
cfg_description = '(unused)'
cfg_cmakelists = 'CMakeLists.txt'
cfg_readme = 'Readme.md'
cfg_license = 'LICENSE.txt'
cfg_ref_prefix = 'v'
cfg_sha512 = 'dadeda'
cfg_vcpkg_description = '(no description found)'
cfg_vcpkg_root = os.environ['VCPKG_ROOT']
cfg_cmake_optpfx = "EXPECTED_LITE"
# End configuration.
# vcpkg control and port templates:
tpl_path_vcpkg_control = '{vcpkg}/ports/{prj}/CONTROL'
tpl_path_vcpkg_portfile = '{vcpkg}/ports/{prj}/portfile.cmake'
tpl_vcpkg_control =\
"""Source: {prj}
Version: {ver}
Description: {desc}"""
tpl_vcpkg_portfile =\
"""include(vcpkg_common_functions)
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO {usr}/{prj}
REF {ref}
SHA512 {sha}
)
vcpkg_configure_cmake(
SOURCE_PATH ${{SOURCE_PATH}}
PREFER_NINJA
OPTIONS
-D{optpfx}_OPT_BUILD_TESTS=OFF
-D{optpfx}_OPT_BUILD_EXAMPLES=OFF
)
vcpkg_install_cmake()
vcpkg_fixup_cmake_targets(
CONFIG_PATH lib/cmake/${{PORT}}
)
file(REMOVE_RECURSE
${{CURRENT_PACKAGES_DIR}}/debug
${{CURRENT_PACKAGES_DIR}}/lib
)
file(INSTALL
${{SOURCE_PATH}}/{lic} DESTINATION ${{CURRENT_PACKAGES_DIR}}/share/${{PORT}} RENAME copyright
)"""
tpl_vcpkg_note_sha =\
"""
Next actions:
- Obtain package SHA: 'vcpkg install {prj}', copy SHA mentioned in 'Actual hash: [...]'
- Add SHA to package: 'script\create-vcpkg --sha={sha}'
- Install package : 'vcpkg install {prj}'"""
tpl_vcpkg_note_install =\
"""
Next actions:
- Install package: 'vcpkg install {prj}'"""
# End of vcpkg templates
def versionFrom( filename ):
"""Obtain version from CMakeLists.txt"""
with open( filename, 'r' ) as f:
content = f.read()
version = re.search(r'VERSION\s(\d+\.\d+\.\d+)', content).group(1)
return version
def descriptionFrom( filename ):
"""Obtain description from CMakeLists.txt"""
with open( filename, 'r' ) as f:
content = f.read()
description = re.search(r'DESCRIPTION\s"(.*)"', content).group(1)
return description if description else cfg_vcpkg_description
def vcpkgRootFrom( path ):
return path if path else './vcpkg'
def to_ref( version ):
"""Add prefix to version/tag, like v1.2.3"""
return cfg_ref_prefix + version
def control_path( args ):
"""Create path like vcpks/ports/_project_/CONTROL"""
return tpl_path_vcpkg_control.format( vcpkg=args.vcpkg_root, prj=args.project )
def portfile_path( args ):
"""Create path like vcpks/ports/_project_/portfile.cmake"""
return tpl_path_vcpkg_portfile.format( vcpkg=args.vcpkg_root, prj=args.project )
def createControl( args ):
"""Create vcpkg CONTROL file"""
output = tpl_vcpkg_control.format(
prj=args.project, ver=args.version, desc=args.description )
if args.verbose:
print( "Creating control file '{f}':".format( f=control_path( args ) ) )
if args.verbose > 1:
print( output )
os.makedirs( os.path.dirname( control_path( args ) ), exist_ok=True )
with open( control_path( args ), 'w') as f:
print( output, file=f )
def createPortfile( args ):
"""Create vcpkg portfile"""
output = tpl_vcpkg_portfile.format(
optpfx=cfg_cmake_optpfx, usr=args.user, prj=args.project, ref=to_ref(args.version), sha=args.sha, lic=cfg_license )
if args.verbose:
print( "Creating portfile '{f}':".format( f=portfile_path( args ) ) )
if args.verbose > 1:
print( output )
os.makedirs( os.path.dirname( portfile_path( args ) ), exist_ok=True )
with open( portfile_path( args ), 'w') as f:
print( output, file=f )
def printNotes( args ):
if args.sha == cfg_sha512:
print( tpl_vcpkg_note_sha.
format( prj=args.project, sha='...' ) )
else:
print( tpl_vcpkg_note_install.
format( prj=args.project ) )
def createVcpkg( args ):
print( "Creating vcpkg for '{usr}/{prj}', version '{ver}' in folder '{vcpkg}':".
format( usr=args.user, prj=args.project, ver=args.version, vcpkg=args.vcpkg_root, ) )
createControl( args )
createPortfile( args )
printNotes( args )
def createVcpkgFromCommandLine():
"""Collect arguments from the commandline and create vcpkg."""
parser = argparse.ArgumentParser(
description='Create microsoft vcpkg.',
epilog="""""",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'-v', '--verbose',
action='count',
default=0,
help='level of progress reporting')
parser.add_argument(
'--user',
metavar='u',
type=str,
default=cfg_github_user,
help='github user name')
parser.add_argument(
'--project',
metavar='p',
type=str,
default=cfg_github_project,
help='github project name')
parser.add_argument(
'--description',
metavar='d',
type=str,
# default=cfg_description,
default=descriptionFrom( cfg_cmakelists ),
help='vcpkg description [from ' + cfg_cmakelists + ']')
parser.add_argument(
'--version',
metavar='v',
type=str,
default=versionFrom( cfg_cmakelists ),
help='version number [from ' + cfg_cmakelists + ']')
parser.add_argument(
'--sha',
metavar='s',
type=str,
default=cfg_sha512,
help='sha of package')
parser.add_argument(
'--vcpkg-root',
metavar='r',
type=str,
default=vcpkgRootFrom( cfg_vcpkg_root ),
help='parent folder containing ports to write files to')
createVcpkg( parser.parse_args() )
if __name__ == '__main__':
createVcpkgFromCommandLine()
# end of file

View File

@@ -0,0 +1,129 @@
#!/usr/bin/env python
#
# Copyright 2017-2018 by Martin Moene
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# script/update-version.py
#
from __future__ import print_function
import argparse
import os
import re
import sys
# Configuration:
table = (
# path, substitute find, substitute format
( 'CMakeLists.txt'
, r'\W{2,4}VERSION\W+([0-9]+\.[0-9]+\.[0-9]+)\W*$'
, ' VERSION {major}.{minor}.{patch}' )
, ( 'CMakeLists.txt'
, r'set\W+expected_lite_version\W+"([0-9]+\.[0-9]+\.[0-9]+)"\W+$'
, 'set( expected_lite_version "{major}.{minor}.{patch}" )\n' )
# , ( 'example/cmake-pkg/CMakeLists.txt'
# , r'set\W+expected_lite_version\W+"([0-9]+\.[0-9]+(\.[0-9]+)?)"\W+$'
# , 'set( expected_lite_version "{major}.{minor}" )\n' )
#
# , ( 'script/install-xxx-pkg.py'
# , r'\expected_lite_version\s+=\s+"([0-9]+\.[0-9]+\.[0-9]+)"\s*$'
# , 'expected_lite_version = "{major}.{minor}.{patch}"\n' )
, ( 'conanfile.py'
, r'version\s+=\s+"([0-9]+\.[0-9]+\.[0-9]+)"\s*$'
, 'version = "{major}.{minor}.{patch}"' )
, ( 'include/nonstd/expected.hpp'
, r'\#define\s+expected_lite_MAJOR\s+[0-9]+\s*$'
, '#define expected_lite_MAJOR {major}' )
, ( 'include/nonstd/expected.hpp'
, r'\#define\s+expected_lite_MINOR\s+[0-9]+\s*$'
, '#define expected_lite_MINOR {minor}' )
, ( 'include/nonstd/expected.hpp'
, r'\#define\s+expected_lite_PATCH\s+[0-9]+\s*$'
, '#define expected_lite_PATCH {patch}\n' )
)
# End configuration.
def readFile( in_path ):
"""Return content of file at given path"""
with open( in_path, 'r' ) as in_file:
contents = in_file.read()
return contents
def writeFile( out_path, contents ):
"""Write contents to file at given path"""
with open( out_path, 'w' ) as out_file:
out_file.write( contents )
def replaceFile( output_path, input_path ):
# prevent race-condition (Python 3.3):
if sys.version_info >= (3, 3):
os.replace( output_path, input_path )
else:
os.remove( input_path )
os.rename( output_path, input_path )
def editFileToVersion( version, info, verbose ):
"""Update version given file path, version regexp and new version format in info"""
major, minor, patch = version.split('.')
in_path, ver_re, ver_fmt = info
out_path = in_path + '.tmp'
new_text = ver_fmt.format( major=major, minor=minor, patch=patch )
if verbose:
print( "- {path} => '{text}':".format( path=in_path, text=new_text.strip('\n') ) )
writeFile(
out_path,
re.sub(
ver_re, new_text, readFile( in_path )
, count=0, flags=re.MULTILINE
)
)
replaceFile( out_path, in_path )
def editFilesToVersion( version, table, verbose ):
if verbose:
print( "Editing files to version {v}:".format(v=version) )
for item in table:
editFileToVersion( version, item, verbose )
def editFilesToVersionFromCommandLine():
"""Update version number given on command line in paths from configuration table."""
parser = argparse.ArgumentParser(
description='Update version number in files.',
epilog="""""",
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument(
'version',
metavar='version',
type=str,
nargs=1,
help='new version number, like 1.2.3')
parser.add_argument(
'-v', '--verbose',
action='store_true',
help='report the name of the file being processed')
args = parser.parse_args()
editFilesToVersion( args.version[0], table, args.verbose )
if __name__ == '__main__':
editFilesToVersionFromCommandLine()
# end of file

View File

@@ -0,0 +1,114 @@
#!/usr/bin/env python
#
# Copyright 2019-2019 by Martin Moene
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# script/upload-conan.py
#
from __future__ import print_function
import argparse
import os
import re
import sys
import subprocess
# Configuration:
def_conan_project = 'expected-lite'
def_conan_user = 'nonstd-lite'
def_conan_channel = 'stable'
cfg_conanfile = 'conanfile.py'
tpl_conan_create = 'conan create . {usr}/{chn}'
tpl_conan_upload = 'conan upload --remote {usr} {prj}/{ver}@{usr}/{chn}'
# End configuration.
def versionFrom( filename ):
"""Obtain version from conanfile.py"""
with open( filename ) as f:
content = f.read()
version = re.search(r'version\s=\s"(.*)"', content).group(1)
return version
def createConanPackage( args ):
"""Create conan package and upload it."""
cmd = tpl_conan_create.format(usr=args.user, chn=args.channel)
if args.verbose:
print( "> {}".format(cmd) )
if not args.dry_run:
subprocess.call( cmd, shell=False )
def uploadConanPackage( args ):
"""Create conan package and upload it."""
cmd = tpl_conan_upload.format(prj=args.project, usr=args.user, chn=args.channel, ver=args.version)
if args.verbose:
print( "> {}".format(cmd) )
if not args.dry_run:
subprocess.call( cmd, shell=False )
def uploadToConan( args ):
"""Create conan package and upload it."""
print( "Updating project '{prj}' to user '{usr}', channel '{chn}', version {ver}:".
format(prj=args.project, usr=args.user, chn=args.channel, ver=args.version) )
createConanPackage( args )
uploadConanPackage( args )
def uploadToConanFromCommandLine():
"""Collect arguments from the commandline and create conan package and upload it."""
parser = argparse.ArgumentParser(
description='Create conan package and upload it to conan.',
epilog="""""",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'-n', '--dry-run',
action='store_true',
help='do not execute conan commands')
parser.add_argument(
'-v', '--verbose',
action='count',
default=0,
help='level of progress reporting')
parser.add_argument(
'--project',
metavar='p',
type=str,
default=def_conan_project,
help='conan project')
parser.add_argument(
'--user',
metavar='u',
type=str,
default=def_conan_user,
help='conan user')
parser.add_argument(
'--channel',
metavar='c',
type=str,
default=def_conan_channel,
help='conan channel')
parser.add_argument(
'--version',
metavar='v',
type=str,
default=versionFrom( cfg_conanfile ),
help='version number [from conanfile.py]')
uploadToConan( parser.parse_args() )
if __name__ == '__main__':
uploadToConanFromCommandLine()
# end of file

View File

@@ -0,0 +1,233 @@
# Copyright 2016-2018 by Martin Moene
#
# https://github.com/martinmoene/expected-lite
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
if( NOT DEFINED CMAKE_MINIMUM_REQUIRED_VERSION )
cmake_minimum_required( VERSION 3.5 FATAL_ERROR )
endif()
project( test LANGUAGES CXX )
set( unit_name "expected" )
set( PACKAGE ${unit_name}-lite )
set( PROGRAM ${unit_name}-lite )
set( SOURCES ${unit_name}-main.t.cpp ${unit_name}.t.cpp )
set( TWEAKD "." )
message( STATUS "Subproject '${PROJECT_NAME}', programs '${PROGRAM}-*'")
set( OPTIONS "" )
set( DEFCMN "-Dlest_FEATURE_AUTO_REGISTER=1" )
set( HAS_STD_FLAGS FALSE )
set( HAS_CPP98_FLAG FALSE )
set( HAS_CPP11_FLAG FALSE )
set( HAS_CPP14_FLAG FALSE )
set( HAS_CPP17_FLAG FALSE )
set( HAS_CPP20_FLAG FALSE )
set( HAS_CPPLATEST_FLAG FALSE )
if ( EXPEXTED_P0323R LESS "99" )
set( DEFCMN ${DEFCMN} "-Dnsel_P0323R=${EXPEXTED_P0323R}" )
endif()
if( MSVC )
message( STATUS "Matched: MSVC")
set( HAS_STD_FLAGS TRUE )
set( OPTIONS -W3 -EHsc )
set( DEFINITIONS -D_SCL_SECURE_NO_WARNINGS ${DEFCMN} )
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.00 )
set( HAS_CPP14_FLAG TRUE )
set( HAS_CPPLATEST_FLAG TRUE )
endif()
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.11 )
set( HAS_CPP17_FLAG TRUE )
endif()
elseif( CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang" )
message( STATUS "CompilerId: '${CMAKE_CXX_COMPILER_ID}'")
set( HAS_STD_FLAGS TRUE )
set( HAS_CPP98_FLAG TRUE )
set( OPTIONS -Wall -Wextra -Wconversion -Wsign-conversion -Wno-missing-braces -fno-elide-constructors )
set( DEFINITIONS ${DEFCMN} )
# GNU: available -std flags depends on version
if( CMAKE_CXX_COMPILER_ID MATCHES "GNU" )
message( STATUS "Matched: GNU")
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8.0 )
set( HAS_CPP11_FLAG TRUE )
endif()
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.2 )
set( HAS_CPP14_FLAG TRUE )
endif()
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.1.0 )
set( HAS_CPP17_FLAG TRUE )
endif()
# AppleClang: available -std flags depends on version
elseif( CMAKE_CXX_COMPILER_ID MATCHES "AppleClang" )
message( STATUS "Matched: AppleClang")
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0.0 )
set( HAS_CPP11_FLAG TRUE )
endif()
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1.0 )
set( HAS_CPP14_FLAG TRUE )
endif()
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.2.0 )
set( HAS_CPP17_FLAG TRUE )
endif()
# Clang: available -std flags depends on version
elseif( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
message( STATUS "Matched: Clang")
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.3.0 )
set( HAS_CPP11_FLAG TRUE )
endif()
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4.0 )
set( HAS_CPP14_FLAG TRUE )
endif()
if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0.0 )
set( HAS_CPP17_FLAG TRUE )
endif()
endif()
elseif( CMAKE_CXX_COMPILER_ID MATCHES "Intel" )
# as is
message( STATUS "Matched: Intel")
else()
# as is
message( STATUS "Matched: nothing")
endif()
# enable MS C++ Core Guidelines checker if MSVC:
function( enable_msvs_guideline_checker target )
if( MSVC )
set_target_properties( ${target} PROPERTIES
VS_GLOBAL_EnableCppCoreCheck true
VS_GLOBAL_CodeAnalysisRuleSet CppCoreCheckRules.ruleset
VS_GLOBAL_RunCodeAnalysis true )
endif()
endfunction()
# make target, compile for given standard if specified:
function( make_target target std )
message( STATUS "Make target: '${std}'" )
add_executable ( ${target} ${SOURCES} )
target_include_directories( ${target} SYSTEM PRIVATE lest )
target_include_directories( ${target} PRIVATE ${TWEAKD} )
target_link_libraries ( ${target} PRIVATE ${PACKAGE} )
target_compile_options ( ${target} PRIVATE ${OPTIONS} )
target_compile_definitions( ${target} PRIVATE ${DEFINITIONS} )
if( std )
if( MSVC )
target_compile_options( ${target} PRIVATE -std:c++${std} )
else()
# Necessary for clang 3.x:
target_compile_options( ${target} PRIVATE -std=c++${std} )
# Ok for clang 4 and later:
# set( CMAKE_CXX_STANDARD ${std} )
# set( CMAKE_CXX_STANDARD_REQUIRED ON )
# set( CMAKE_CXX_EXTENSIONS OFF )
endif()
endif()
endfunction()
# add generic executable, unless -std flags can be specified:
if( NOT HAS_STD_FLAGS )
make_target( ${PROGRAM}.t "" )
else()
# # unconditionally add C++98 variant as MSVC has no option for it:
# if( HAS_CPP98_FLAG )
# make_target( ${PROGRAM}-cpp98.t 98 )
# else()
# make_target( ${PROGRAM}-cpp98.t "" )
# endif()
# unconditionally add C++11 variant as MSVC has no option for it:
if( HAS_CPP11_FLAG )
make_target( ${PROGRAM}-cpp11.t 11 )
else()
make_target( ${PROGRAM}-cpp11.t "" )
endif()
if( HAS_CPP14_FLAG )
make_target( ${PROGRAM}-cpp14.t 14 )
endif()
if( HAS_CPP17_FLAG )
set( std17 17 )
if( CMAKE_CXX_COMPILER_ID MATCHES "AppleClang" )
set( std17 1z )
endif()
make_target( ${PROGRAM}-cpp17.t ${std17} )
enable_msvs_guideline_checker( ${PROGRAM}-cpp17.t )
endif()
if( HAS_CPPLATEST_FLAG )
make_target( ${PROGRAM}-cpplatest.t latest )
endif()
endif()
# with C++20, honour explicit request for std::expected or nonstd::expected:
if( HAS_CPP20_FLAG )
set( WHICH nsel_EXPECTED_DEFAULT )
if( EXPECTED_LITE_OPT_SELECT_STD )
set( WHICH nsel_EXPECTED_STD )
elseif( EXPECTED_LITE_OPT_SELECT_NONSTD )
set( WHICH nsel_EXPECTED_NONSTD )
endif()
target_compile_definitions( ${PROGRAM}-cpp17.t PRIVATE nsel_CONFIG_SELECT_EXPECTED=${WHICH} )
if( HAS_CPPLATEST_FLAG )
target_compile_definitions( ${PROGRAM}-cpplatest.t PRIVATE nsel_CONFIG_SELECT_EXPECTED=${WHICH} )
endif()
endif()
# configure unit tests via CTest:
enable_testing()
if( HAS_STD_FLAGS )
# # unconditionally add C++98 variant for MSVC:
# add_test( NAME test-cpp98 COMMAND ${PROGRAM}-cpp98.t )
#
# unconditionally add C++11 variant for MSVC:
add_test( NAME test-cpp11 COMMAND ${PROGRAM}-cpp11.t )
if( HAS_CPP14_FLAG )
add_test( NAME test-cpp14 COMMAND ${PROGRAM}-cpp14.t )
endif()
if( HAS_CPP17_FLAG )
add_test( NAME test-cpp17 COMMAND ${PROGRAM}-cpp17.t )
endif()
if( HAS_CPPLATEST_FLAG )
add_test( NAME test-cpplatest COMMAND ${PROGRAM}-cpplatest.t )
endif()
else()
add_test( NAME test COMMAND ${PROGRAM}.t --pass )
add_test( NAME list_version COMMAND ${PROGRAM}.t --version )
add_test( NAME list_tags COMMAND ${PROGRAM}.t --list-tags )
add_test( NAME list_tests COMMAND ${PROGRAM}.t --list-tests )
endif()
# end of file

View File

@@ -0,0 +1,131 @@
// Copyright (c) 2016-2018 Martin Moene
//
// https://github.com/martinmoene/expected-lite
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "expected-main.t.hpp"
#define expected_PRESENT( x ) \
std::cout << #x << ": " << x << "\n"
#define expected_ABSENT( x ) \
std::cout << #x << ": (undefined)\n"
// Suppress:
// - unused parameter, for cases without assertions such as [.std...]
#if defined(__clang__)
# pragma clang diagnostic ignored "-Wunused-parameter"
#elif defined __GNUC__
# pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
lest::tests & specification()
{
static lest::tests tests;
return tests;
}
CASE( "expected-lite version" "[.expected][.version]" )
{
expected_PRESENT( expected_lite_MAJOR );
expected_PRESENT( expected_lite_MINOR );
expected_PRESENT( expected_lite_PATCH );
expected_PRESENT( expected_lite_VERSION );
}
CASE( "any configuration" "[.expected][.config]" )
{
expected_PRESENT( nsel_HAVE_STD_EXPECTED );
expected_PRESENT( nsel_USES_STD_EXPECTED );
expected_PRESENT( nsel_EXPECTED_DEFAULT );
expected_PRESENT( nsel_EXPECTED_NONSTD );
expected_PRESENT( nsel_EXPECTED_STD );
expected_PRESENT( nsel_CONFIG_SELECT_EXPECTED );
expected_PRESENT( nsel_CONFIG_NO_EXCEPTIONS );
expected_PRESENT( nsel_CPLUSPLUS );
}
CASE( "__cplusplus" "[.stdc++]" )
{
expected_PRESENT( __cplusplus );
#ifdef _MSVC_LANG
expected_PRESENT( _MSVC_LANG );
#else
expected_ABSENT( _MSVC_LANG );
#endif
}
CASE( "Compiler version" "[.compiler]" )
{
#if nsel_USES_STD_EXPECTED
std::cout << "(Compiler version not available: using std::expected)\n";
#else
expected_PRESENT( nsel_COMPILER_CLANG_VERSION );
expected_PRESENT( nsel_COMPILER_GNUC_VERSION );
expected_PRESENT( nsel_COMPILER_MSVC_VERSION );
#endif
}
CASE( "presence of C++ language features" "[.stdlanguage]" )
{
#if nsel_USES_STD_EXPECTED
std::cout << "(Presence of C++ language features not available: using std::expected)\n";
#else
std::cout << "[.stdlanguage]: none\n";
#endif
}
CASE( "presence of C++ library features" "[.stdlibrary]" )
{
#if nsel_USES_STD_EXPECTED
std::cout << "(Presence of C++ library features not available: using std::expected)\n";
#else
#ifdef __cpp_exceptions
expected_PRESENT( __cpp_exceptions );
#else
expected_ABSENT( __cpp_exceptions );
#endif
#ifdef __EXCEPTIONS
expected_PRESENT( __EXCEPTIONS );
#else
expected_ABSENT( __EXCEPTIONS );
#endif
#ifdef _HAS_EXCEPTIONS
expected_PRESENT( _HAS_EXCEPTIONS );
#else
expected_ABSENT( _HAS_EXCEPTIONS );
#endif
#ifdef _CPPUNWIND
expected_PRESENT( _CPPUNWIND );
#else
expected_ABSENT( _CPPUNWIND );
#endif
#endif
}
int main( int argc, char * argv[] )
{
return lest::run( specification(), argc, argv );
}
#if 0
g++ -I../include -o expected-lite.t.exe expected-lite.t.cpp && expected-lite.t.exe --pass
g++ -std=c++98 -I../include -o expected-lite.t.exe expected-lite.t.cpp && expected-lite.t.exe --pass
g++ -std=c++03 -I../include -o expected-lite.t.exe expected-lite.t.cpp && expected-lite.t.exe --pass
g++ -std=c++0x -I../include -o expected-lite.t.exe expected-lite.t.cpp && expected-lite.t.exe --pass
g++ -std=c++11 -I../include -o expected-lite.t.exe expected-lite.t.cpp && expected-lite.t.exe --pass
g++ -std=c++14 -I../include -o expected-lite.t.exe expected-lite.t.cpp && expected-lite.t.exe --pass
g++ -std=c++17 -I../include -o expected-lite.t.exe expected-lite.t.cpp && expected-lite.t.exe --pass
cl -EHsc -I../include expected-lite.t.cpp && expected-lite.t.exe --pass
#endif
// end of file

View File

@@ -0,0 +1,74 @@
// Copyright (c) 2016-2018 Martin Moene
//
// https://github.com/martinmoene/expected-lite
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#pragma once
#ifndef TEST_EXPECTED_LITE_H_INCLUDED
#define TEST_EXPECTED_LITE_H_INCLUDED
// Limit C++ Core Guidelines checking to expected-lite:
#include "nonstd/expected.hpp"
#if nsel_COMPILER_MSVC_VER >= 1910
# include <CppCoreCheck/Warnings.h>
# pragma warning(disable: ALL_CPPCORECHECK_WARNINGS)
#endif
#include <iosfwd>
namespace lest {
template< typename T, typename E >
std::ostream & operator<<( std::ostream & os, nonstd::expected<T,E> const & );
template< typename E >
std::ostream & operator<<( std::ostream & os, nonstd::expected<void,E> const & );
} // namespace lest
// Compiler warning suppression for usage of lest:
#ifdef __clang__
# pragma clang diagnostic ignored "-Wstring-conversion"
# pragma clang diagnostic ignored "-Wunused-parameter"
# pragma clang diagnostic ignored "-Wunused-template"
# pragma clang diagnostic ignored "-Wunused-function"
# pragma clang diagnostic ignored "-Wunused-member-function"
#elif defined __GNUC__
# pragma GCC diagnostic ignored "-Wunused-parameter"
# pragma GCC diagnostic ignored "-Wunused-function"
#endif
#include "lest.hpp"
#define CASE( name ) lest_CASE( specification(), name )
extern lest::tests & specification();
namespace lest {
// use oparator<< instead of to_string() overload;
// see http://stackoverflow.com/a/10651752/437272
template< typename T, typename E >
inline std::ostream & operator<<( std::ostream & os, nonstd::expected<T,E> const & v )
{
using lest::to_string;
return os << "[expected:" << (v ? to_string(*v) : "[empty]") << "]";
}
template< typename E >
inline std::ostream & operator<<( std::ostream & os, nonstd::expected<void,E> const & v )
{
using lest::to_string;
return os << "[expected<void>:" << (v ? "[non-empty]" : "[empty]") << "]";
}
} // namespace lest
#endif // TEST_EXPECTED_LITE_H_INCLUDED
// end of file

View File

@@ -0,0 +1,78 @@
// Copyright (c) 2016-2020 Martin Moene
//
// https://github.com/martinmoene/expected-lite
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "nonstd/expected.hpp"
#include <iostream>
template< typename T >
void use( T const & /*x*/) {}
#define expected_PRESENT( x ) \
std::cout << #x << ": " << x << "\n"
#define expected_ABSENT( x ) \
std::cout << #x << ": (undefined)\n"
void report()
{
#ifdef __cpp_exceptions
expected_PRESENT( __cpp_exceptions );
#else
expected_ABSENT( __cpp_exceptions );
#endif
#ifdef __EXCEPTIONS
expected_PRESENT( __EXCEPTIONS );
#else
expected_ABSENT( __EXCEPTIONS );
#endif
#ifdef _HAS_EXCEPTIONS
expected_PRESENT( _HAS_EXCEPTIONS );
#else
expected_ABSENT( _HAS_EXCEPTIONS );
#endif
#ifdef _CPPUNWIND
expected_PRESENT( _CPPUNWIND );
#else
expected_ABSENT( _CPPUNWIND );
#endif
#ifdef _CPPRTTI
expected_PRESENT( _CPPRTTI );
#else
expected_ABSENT( _CPPRTTI );
#endif
}
int violate_access()
{
nonstd::expected<int, char> eu( nonstd:: make_unexpected('a') );
return eu.value();
}
int main()
{
report();
#if ! nsel_CONFIG_NO_EXCEPTIONS_SEH
return violate_access();
#else
__try
{
return violate_access();
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
std::cerr << "\n*** Executing SEH __except block ***\n";
}
#endif
}
// end of file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
#define EXPECTED_TWEAK_VALUE 42

View File

@@ -0,0 +1,3 @@
#include "nonstd/expected.hpp"
MAIN

View File

@@ -0,0 +1,63 @@
@echo off & setlocal enableextensions enabledelayedexpansion
::
:: t.bat - compile & run tests (MSVC).
::
set unit=expected
:: if no std is given, use compiler default
set std=%1
if not "%std%"=="" set std=-std:%std%
call :CompilerVersion version
echo VC%version%: %args%
set UCAP=%unit%
call :toupper UCAP
set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_DEFAULT
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_NONSTD
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_STD
set unit_config=
set msvc_defines=^
-Dlest_FEATURE_AUTO_REGISTER=1 ^
-D_CRT_SECURE_NO_WARNINGS ^
-D_SCL_SECURE_NO_WARNINGS ^
-D_HAS_EXCEPTIONS=0 ^
-Dnsel_CONFIG_NO_SEH=0
:: -Dnsel_CONFIG_NO_EXCEPTIONS=1
set CppCoreCheckInclude=%VCINSTALLDIR%\Auxiliary\VS\include
:: -EHsc
::cl -kernel -GR- -W3 %std% %unit_select% %unit_config% %msvc_defines% -I"%CppCoreCheckInclude%" -I../include -I. %unit%-noexcept.t.cpp && %unit%-noexcept.t.exe
cl -EHs -GR- -W3 %std% %unit_select% %unit_config% %msvc_defines% -I"%CppCoreCheckInclude%" -Ilest -I../include -I. %unit%-noexcept.t.cpp && %unit%-noexcept.t.exe
endlocal & goto :EOF
:: subroutines:
:CompilerVersion version
@echo off & setlocal enableextensions
set tmpprogram=_getcompilerversion.tmp
set tmpsource=%tmpprogram%.c
echo #include ^<stdio.h^> >%tmpsource%
echo int main(){printf("%%d\n",_MSC_VER);} >>%tmpsource%
cl /nologo %tmpsource% >nul
for /f %%x in ('%tmpprogram%') do set version=%%x
del %tmpprogram%.* >nul
set offset=0
if %version% LSS 1900 set /a offset=1
set /a version="version / 10 - 10 * ( 5 + offset )"
endlocal & set %1=%version%& goto :EOF
:: toupper; makes use of the fact that string
:: replacement (via SET) is not case sensitive
:toupper
for %%L IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET %1=!%1:%%L=%%L!
goto :EOF

View File

@@ -0,0 +1,3 @@
cl -EHsc -DMAIN="" -Dnsel_P0323R=-2 -I../include -I. -Foodr1.obj -c odr.cpp
cl -EHsc -DMAIN="int main(){}" -Dnsel_P0323R=-2 -I../include -I. -Foodr2.obj -c odr.cpp
cl odr1.obj odr2.obj

View File

@@ -0,0 +1,57 @@
@echo off & setlocal enableextensions enabledelayedexpansion
::
:: t.bat - compile & run tests (MSVC).
::
set unit=expected
:: if no std is given, use compiler default
set std=%1
if not "%std%"=="" set std=-std:%std%
call :CompilerVersion version
echo VC%version%: %args%
set UCAP=%unit%
call :toupper UCAP
set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_DEFAULT
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_NONSTD
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_STD
set unit_config=
set msvc_defines=^
-Dlest_FEATURE_AUTO_REGISTER=1 ^
-D_CRT_SECURE_NO_WARNINGS ^
-D_SCL_SECURE_NO_WARNINGS
set CppCoreCheckInclude=%VCINSTALLDIR%\Auxiliary\VS\include
cl -nologo -W3 -EHsc %std% %unit_select% %unit_config% %msvc_defines% -I"%CppCoreCheckInclude%" -Ilest -I../include -I. %unit%-main.t.cpp %unit%.t.cpp && %unit%-main.t.exe
endlocal & goto :EOF
:: subroutines:
:CompilerVersion version
@echo off & setlocal enableextensions
set tmpprogram=_getcompilerversion.tmp
set tmpsource=%tmpprogram%.c
echo #include ^<stdio.h^> >%tmpsource%
echo int main(){printf("%%d\n",_MSC_VER);} >>%tmpsource%
cl /nologo %tmpsource% >nul
for /f %%x in ('%tmpprogram%') do set version=%%x
del %tmpprogram%.* >nul
set offset=0
if %version% LSS 1900 set /a offset=1
set /a version="version / 10 - 10 * ( 5 + offset )"
endlocal & set %1=%version%& goto :EOF
:: toupper; makes use of the fact that string
:: replacement (via SET) is not case sensitive
:toupper
for %%L IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET %1=!%1:%%L=%%L!
goto :EOF

View File

@@ -0,0 +1,60 @@
@echo off & setlocal enableextensions enabledelayedexpansion
::
:: tc-cl.bat - compile & run tests (clang-cl).
::
set unit=expected
set unit_file=%unit%
:: if no std is given, use c++14
set std=c++14
if NOT "%1" == "" set std=%1 & shift
set UCAP=%unit%
call :toupper UCAP
set unit_select=%unit%_%UCAP%_NONSTD
::set unit_select=%unit%_CONFIG_SELECT_%UCAP%_NONSTD
if NOT "%1" == "" set unit_select=%1 & shift
set args=%1 %2 %3 %4 %5 %6 %7 %8 %9
set clang=clang-cl
call :CompilerVersion version
echo %clang% %version%: %std% %unit_select% %args%
set unit_config=^
-Dlest_FEATURE_AUTO_REGISTER=1 ^
-D%unit%_%UCAP%_HEADER=\"nonstd/%unit%.hpp\" ^
-D%unit%_TEST_NODISCARD=0 ^
-D%unit%_CONFIG_SELECT_%UCAP%=%unit_select%
rem -flto / -fwhole-program
set optflags=-O2
set warnflags=-Wall -Wextra -Wpedantic -Weverything -Wshadow -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded -Wno-missing-noreturn -Wno-documentation-unknown-command -Wno-documentation-deprecated-sync -Wno-documentation -Wno-weak-vtables -Wno-missing-prototypes -Wno-missing-variable-declarations -Wno-exit-time-destructors -Wno-global-constructors -Wno-sign-conversion -Wno-sign-compare -Wno-implicit-int-conversion -Wno-deprecated-declarations -Wno-date-time
"%clang%" -EHsc -std:%std% %optflags% %warnflags% %unit_config% -fms-compatibility-version=19.00 /imsvc lest -I../include -Ics_string -I. -o %unit_file%-main.t.exe %unit_file%-main.t.cpp %unit_file%.t.cpp && %unit_file%-main.t.exe
endlocal & goto :EOF
:: subroutines:
:CompilerVersion version
echo off & setlocal enableextensions
set tmpprogram=_getcompilerversion.tmp
set tmpsource=%tmpprogram%.c
echo #include ^<stdio.h^> > %tmpsource%
echo int main(){printf("%%d.%%d.%%d\n",__clang_major__,__clang_minor__,__clang_patchlevel__);} >> %tmpsource%
"%clang%" -m32 -o %tmpprogram% %tmpsource% >nul
for /f %%x in ('%tmpprogram%') do set version=%%x
del %tmpprogram%.* >nul
endlocal & set %1=%version%& goto :EOF
:: toupper; makes use of the fact that string
:: replacement (via SET) is not case sensitive
:toupper
for %%L IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET %1=!%1:%%L=%%L!
goto :EOF

View File

@@ -0,0 +1,53 @@
@echo off & setlocal enableextensions enabledelayedexpansion
::
:: tc.bat - compile & run tests (clang).
::
set unit=expected
:: if no std is given, use c++14
set std=%1
if "%std%"=="" set std=c++14
set clang=clang
call :CompilerVersion version
echo %clang% %version%: %std%
set UCAP=%unit%
call :toupper UCAP
set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_DEFAULT
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_NONSTD
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_STD
set unit_config=
rem -flto / -fwhole-program
set optflags=-O2 -fno-exceptions
set warnflags=-Wall -Wextra -Wpedantic -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded -Wno-missing-noreturn -Wno-documentation-unknown-command -Wno-documentation-deprecated-sync -Wno-documentation -Wno-weak-vtables -Wno-missing-prototypes -Wno-missing-variable-declarations -Wno-exit-time-destructors -Wno-global-constructors
"%clang%" -m32 -std=%std% %optflags% %warnflags% %unit_select% %unit_config% -Dlest_FEATURE_AUTO_REGISTER=1 -fms-compatibility-version=19.00 -isystem "%VCInstallDir%include" -isystem "%WindowsSdkDir_71A%include" -I../include -I. -o %unit%-main.t.exe %unit%-noexcept.t.cpp && %unit%-noexcept.t.exe
endlocal & goto :EOF
:: subroutines:
:CompilerVersion version
echo off & setlocal enableextensions
set tmpprogram=_getcompilerversion.tmp
set tmpsource=%tmpprogram%.c
echo #include ^<stdio.h^> > %tmpsource%
echo int main(){printf("%%d.%%d.%%d\n",__clang_major__,__clang_minor__,__clang_patchlevel__);} >> %tmpsource%
"%clang%" -m32 -o %tmpprogram% %tmpsource% >nul
for /f %%x in ('%tmpprogram%') do set version=%%x
del %tmpprogram%.* >nul
endlocal & set %1=%version%& goto :EOF
:: toupper; makes use of the fact that string
:: replacement (via SET) is not case sensitive
:toupper
for %%L IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET %1=!%1:%%L=%%L!
goto :EOF

View File

@@ -0,0 +1,53 @@
@echo off & setlocal enableextensions enabledelayedexpansion
::
:: tc.bat - compile & run tests (clang).
::
set unit=expected
:: if no std is given, use c++14
set std=%1
if "%std%"=="" set std=c++14
set clang=clang
call :CompilerVersion version
echo %clang% %version%: %std%
set UCAP=%unit%
call :toupper UCAP
set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_DEFAULT
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_NONSTD
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_STD
set unit_config=
rem -flto / -fwhole-program
set optflags=-O2
set warnflags=-Wall -Wextra -Wpedantic -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded -Wno-missing-noreturn -Wno-documentation-unknown-command -Wno-documentation-deprecated-sync -Wno-documentation -Wno-weak-vtables -Wno-missing-prototypes -Wno-missing-variable-declarations -Wno-exit-time-destructors -Wno-global-constructors
"%clang%" -m32 -std=%std% %optflags% %warnflags% %unit_select% %unit_config% -Dlest_FEATURE_AUTO_REGISTER=1 -fms-compatibility-version=19.00 -isystem "%VCInstallDir%include" -isystem "%WindowsSdkDir_71A%include" -isystem lest -I../include -I. -o %unit%-main.t.exe %unit%-main.t.cpp %unit%.t.cpp && %unit%-main.t.exe
endlocal & goto :EOF
:: subroutines:
:CompilerVersion version
echo off & setlocal enableextensions
set tmpprogram=_getcompilerversion.tmp
set tmpsource=%tmpprogram%.c
echo #include ^<stdio.h^> > %tmpsource%
echo int main(){printf("%%d.%%d.%%d\n",__clang_major__,__clang_minor__,__clang_patchlevel__);} >> %tmpsource%
"%clang%" -m32 -o %tmpprogram% %tmpsource% >nul
for /f %%x in ('%tmpprogram%') do set version=%%x
del %tmpprogram%.* >nul
endlocal & set %1=%version%& goto :EOF
:: toupper; makes use of the fact that string
:: replacement (via SET) is not case sensitive
:toupper
for %%L IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET %1=!%1:%%L=%%L!
goto :EOF

View File

@@ -0,0 +1,3 @@
@for %%s in ( c++98 c++03 c++11 c++14 c++17 ) do (
call tg.bat %%s
)

View File

@@ -0,0 +1,55 @@
@echo off & setlocal enableextensions enabledelayedexpansion
::
:: tg.bat - compile & run tests (GNUC).
::
set unit=expected
:: if no std is given, use c++11
set std=%1
set args=%2 %3 %4 %5 %6 %7 %8 %9
if "%1" == "" set std=c++11
set gpp=g++
call :CompilerVersion version
echo %gpp% %version%: %std% %args%
set UCAP=%unit%
call :toupper UCAP
set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_DEFAULT
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_NONSTD
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_STD
set unit_config=-Dnsel_CONFIG_NO_EXCEPTIONS=1
rem -flto / -fwhole-program
set optflags=-O2 -fno-exceptions
set warnflags=-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wno-padded -Wno-missing-noreturn
%gpp% -std=%std% %optflags% %warnflags% %unit_select% %unit_config% -o %unit%-main.t.exe -Dlest_FEATURE_AUTO_REGISTER=1 -I../include -I. %unit%-noexcept.t.cpp && %unit%-main.t.exe
endlocal & goto :EOF
:: subroutines:
:CompilerVersion version
echo off & setlocal enableextensions
set tmpprogram=_getcompilerversion.tmp
set tmpsource=%tmpprogram%.c
echo #include ^<stdio.h^> > %tmpsource%
echo int main(){printf("%%d.%%d.%%d\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);} >> %tmpsource%
%gpp% -o %tmpprogram% %tmpsource% >nul
for /f %%x in ('%tmpprogram%') do set version=%%x
del %tmpprogram%.* >nul
endlocal & set %1=%version%& goto :EOF
:: toupper; makes use of the fact that string
:: replacement (via SET) is not case sensitive
:toupper
for %%L IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET %1=!%1:%%L=%%L!
goto :EOF

View File

@@ -0,0 +1,55 @@
@echo off & setlocal enableextensions enabledelayedexpansion
::
:: tg.bat - compile & run tests (GNUC).
::
set unit=expected
:: if no std is given, use c++11
set std=%1
set args=%2 %3 %4 %5 %6 %7 %8 %9
if "%1" == "" set std=c++11
set gpp=g++
call :CompilerVersion version
echo %gpp% %version%: %std% %args%
set UCAP=%unit%
call :toupper UCAP
set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_DEFAULT
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_NONSTD
::set unit_select=-D%unit%_CONFIG_SELECT_%UCAP%=%unit%_%UCAP%_STD
set unit_config=
rem -flto / -fwhole-program
set optflags=-O2
set warnflags=-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wno-padded -Wno-missing-noreturn
%gpp% -std=%std% %optflags% %warnflags% %unit_select% %unit_config% -o %unit%-main.t.exe -Dlest_FEATURE_AUTO_REGISTER=1 -isystem lest -I../include -I. %unit%-main.t.cpp %unit%.t.cpp && %unit%-main.t.exe
endlocal & goto :EOF
:: subroutines:
:CompilerVersion version
echo off & setlocal enableextensions
set tmpprogram=_getcompilerversion.tmp
set tmpsource=%tmpprogram%.c
echo #include ^<stdio.h^> > %tmpsource%
echo int main(){printf("%%d.%%d.%%d\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);} >> %tmpsource%
%gpp% -o %tmpprogram% %tmpsource% >nul
for /f %%x in ('%tmpprogram%') do set version=%%x
del %tmpprogram%.* >nul
endlocal & set %1=%version%& goto :EOF
:: toupper; makes use of the fact that string
:: replacement (via SET) is not case sensitive
:toupper
for %%L IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET %1=!%1:%%L=%%L!
goto :EOF