Commit 6fc4b643 authored by Kirk Shoop's avatar Kirk Shoop Committed by Facebook Github Bot

restructure pushmi for folly

Summary:
removed top level project matter
removed old build structure
removed single header
removed nonious
moved include files to root
change include paths to work in folly
add TARGETS files for tests and most examples
commented out catch tests pending gtest migration
added cpp libraries for core, executors and operators
fixes for additional warnings that are enabled in folly

Reviewed By: yfeldblum

Differential Revision: D10438543

fbshipit-source-id: 73af41a2c70cba126e063c6a8cf4363dc7444fef
parent e9ec6e17
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
build/**
\ No newline at end of file
# Copyright Louis Dionne 2013-2016
# Copyright Gonzalo BG 2014-2017
# Copyright Julian Becker 2015
# Copyright Manu Sánchez 2015
# Copyright Casey Carter 2015-2017
# Copyright Eric Niebler 2015-2016
# Copyright Paul Fultz II 2015-2016
# Copyright Jakub Szuppe 2016.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt)
# Adapted from various sources, including:
# - Louis Dionne's Hana: https://github.com/ldionne/hana
# - Paul Fultz II's FIT: https://github.com/pfultz2/Fit
language: cpp
script: cmake
env:
global:
- DEPS_DIR=${TRAVIS_BUILD_DIR}/deps
- CMAKE_VERSION="3.12.0"
cache:
directories:
- ${DEPS_DIR}/cmake-${CMAKE_VERSION}
matrix:
include:
# - env: BUILD_TYPE=Release CPP=14 SYSTEM_LIBCXX=On
# os: osx
# compiler: clang
# clang 5 C++11/14/1z Debug/Release libc++, 11 Debug libstdc++
- env: CLANG_VERSION=6.0 BUILD_TYPE=Debug CPP=14 LIBCXX=On
os: linux
addons: &clang6
apt:
packages:
- clang-6.0
sources:
- llvm-toolchain-trusty-6.0
- ubuntu-toolchain-r-test
- env: CLANG_VERSION=6.0 BUILD_TYPE=Release CPP=14 LIBCXX=On
os: linux
addons: *clang6
- env: CLANG_VERSION=6.0 BUILD_TYPE=Debug CPP=17 LIBCXX=On
os: linux
addons: *clang6
- env: CLANG_VERSION=6.0 BUILD_TYPE=Release CPP=17 LIBCXX=On
os: linux
addons: *clang6
# gcc-6 C++11/14/1z Debug/Release
- env: GCC_VERSION=6 BUILD_TYPE=Debug CPP=14
os: linux
addons: &gcc6
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=6 BUILD_TYPE=Release CPP=14
os: linux
addons: *gcc6
- env: GCC_VERSION=6 BUILD_TYPE=Debug CPP=17
os: linux
addons: *gcc6
- env: GCC_VERSION=6 BUILD_TYPE=Release CPP=17
os: linux
addons: *gcc6
- env: GCC_VERSION=6 BUILD_TYPE=Debug CPP=17 CONCEPTS=On
os: linux
addons: *gcc6
- env: GCC_VERSION=6 BUILD_TYPE=Release CPP=17 CONCEPTS=On
os: linux
addons: *gcc6
# gcc-7 C++11/14/1z Debug/Release
- env: GCC_VERSION=7 BUILD_TYPE=Debug CPP=14
os: linux
addons: &gcc7
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=7 BUILD_TYPE=Release CPP=14
os: linux
addons: *gcc7
- env: GCC_VERSION=7 BUILD_TYPE=Debug CPP=17
os: linux
addons: *gcc7
- env: GCC_VERSION=7 BUILD_TYPE=Release CPP=17
os: linux
addons: *gcc7
- env: GCC_VERSION=7 BUILD_TYPE=Debug CPP=17 CONCEPTS=On
os: linux
addons: *gcc7
- env: GCC_VERSION=7 BUILD_TYPE=Release CPP=17 CONCEPTS=On
os: linux
addons: *gcc7
# gcc-8 C++11/14/1z Debug/Release
- env: GCC_VERSION=8 BUILD_TYPE=Debug CPP=14
os: linux
addons: &gcc8
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=8 BUILD_TYPE=Release CPP=14
os: linux
addons: *gcc8
- env: GCC_VERSION=8 BUILD_TYPE=Debug CPP=17
os: linux
addons: *gcc8
- env: GCC_VERSION=8 BUILD_TYPE=Release CPP=17
os: linux
addons: *gcc8
- env: GCC_VERSION=8 BUILD_TYPE=Debug CPP=17 CONCEPTS=On
os: linux
addons: *gcc8
- env: GCC_VERSION=8 BUILD_TYPE=Release CPP=17 CONCEPTS=On
os: linux
addons: *gcc8
# Install dependencies
before_install:
- export CHECKOUT_PATH=`pwd`;
- |
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
brew update
brew install gnu-sed --with-default-names
brew install gnu-which --with-default-names
fi
- |
if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
if [ -z "$(ls -A ${DEPS_DIR}/cmake-${CMAKE_VERSION}/cached)" ]; then
CMAKE_URL="https://cmake.org/files/v3.12/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz"
mkdir -p ${DEPS_DIR}/cmake-${CMAKE_VERSION}
travis_retry wget --no-check-certificate --quiet -O - "${CMAKE_URL}" | tar --strip-components=1 -xz -C ${DEPS_DIR}/cmake-${CMAKE_VERSION}
touch ${DEPS_DIR}/cmake-${CMAKE_VERSION}/cached
else
echo "Using cached cmake version ${CMAKE_VERSION}."
fi
export PATH="${DEPS_DIR}/cmake-${CMAKE_VERSION}/bin:${PATH}"
else
if ! brew ls --version cmake &>/dev/null; then brew install cmake; fi
fi
- if [ -n "$GCC_VERSION" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi
- if [ -n "$CLANG_VERSION" ]; then export CXX="clang++-${CLANG_VERSION}" CC="clang-${CLANG_VERSION}"; fi
- which $CXX
- which $CC
- $CXX --version
- if [ "$ASAN" == "On" ]; then export SANITIZER="Address;Undefined"; fi
- if [ "$MSAN" == "On" ]; then export SANITIZER="MemoryWithOrigins"; fi
- if [ -n "$CLANG_VERSION" ]; then sudo PATH="${PATH}" CXX="$CXX" CC="$CC" ./install_libcxx.sh; fi
install:
- cd $CHECKOUT_PATH
- mkdir -p build
- cd build
- |
if [ "$LIBCXX" == "On" ]; then
CXX_FLAGS="${CXX_FLAGS} -stdlib=libc++ -nostdinc++ -cxx-isystem /usr/include/c++/v1/ -Wno-unused-command-line-argument"
CXX_LINKER_FLAGS="${CXX_LINKER_FLAGS} -lc++abi"
fi
# Required to test the C++ compiler since libc++ is compiled with ASan enabled:
- if [ -n "$CLANG_VERSION" -a "$ASAN" == "On" -a "$LIBCXX" == "On" ]; then CXX_FLAGS="${CXX_FLAGS} -fsanitize=address"; fi
# Required to test the C++ compiler since libc++ is compiled with MSan enabled:
- if [ -n "$CLANG_VERSION" -a "$MSAN" == "On" -a "$LIBCXX" == "On" ]; then CXX_FLAGS="${CXX_FLAGS} -fsanitize=memory"; fi
- if [ -n "$GCC_VERSION" -a "$CONCEPTS" == "On" ]; then CXX_FLAGS="${CXX_FLAGS} -fconcepts"; fi
- cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" -DCMAKE_EXE_LINKER_FLAGS="${CXX_LINKER_FLAGS}" -DCMAKE_CXX_STANDARD=$CPP -DPUSHMI_CONCEPTS=$CONCEPTS -Wdev
- make -j2 VERBOSE=1
script:
- ctest -j2 -VV ${CTEST_FLAGS}
notifications:
email: false
cmake_minimum_required(VERSION 3.7)
project(pushmi-project CXX)
#
option(PUSHMI_USE_CONCEPTS_EMULATION "Use C++14 Concepts Emulation" ON)
option(PUSHMI_USE_CPP_2A "Use C++2a with concepts emulation" OFF)
option(PUSHMI_USE_CPP_17 "Use C++17 with concepts emulation" OFF)
option(PUSHMI_ONE_TEST_BINARY "Compile all the tests into one binary" OFF)
FIND_PACKAGE (Threads REQUIRED)
add_library(pushmi INTERFACE)
target_include_directories(pushmi INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/executors-impl/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/futures-impl/future-executor-interaction/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/networking-ts-impl/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/nonius/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/executors>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/futures>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/net>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/nonius>
)
if (PUSHMI_USE_CONCEPTS_EMULATION)
message("Using concepts emulation!")
if(${CMAKE_VERSION} VERSION_LESS "3.8.0" OR PUSHMI_USE_CPP_17 OR PUSHMI_USE_CPP_2A)
if (PUSHMI_USE_CPP_17)
message("Using c++17!")
target_compile_options(pushmi INTERFACE
$<$<CXX_COMPILER_ID:GNU>:-std=c++17>
$<$<CXX_COMPILER_ID:AppleClang>:-std=c++17>
$<$<CXX_COMPILER_ID:Clang>:-std=c++17>
)
elseif (PUSHMI_USE_CPP_2A)
message("Using c++2a!")
target_compile_options(pushmi INTERFACE
$<$<CXX_COMPILER_ID:GNU>:-std=c++2a>
$<$<CXX_COMPILER_ID:AppleClang>:-std=c++2a>
$<$<CXX_COMPILER_ID:Clang>:-std=c++2a>
)
else()
message("Using c++14!")
target_compile_options(pushmi INTERFACE
$<$<CXX_COMPILER_ID:GNU>:-std=c++14>
$<$<CXX_COMPILER_ID:AppleClang>:-std=c++14>
$<$<CXX_COMPILER_ID:Clang>:-std=c++14>
)
endif()
else()
target_compile_features(pushmi INTERFACE cxx_std_14)
endif()
else(PUSHMI_USE_CONCEPTS_EMULATION)
message("Using real concepts!")
message("Using c++2a!")
target_compile_options(pushmi INTERFACE
$<$<CXX_COMPILER_ID:GNU>:-std=c++2a>
$<$<CXX_COMPILER_ID:GNU>:-fconcepts>)
endif(PUSHMI_USE_CONCEPTS_EMULATION)
target_compile_options(pushmi INTERFACE
$<$<CXX_COMPILER_ID:GNU>:-ftemplate-backtrace-limit=0>
$<$<CXX_COMPILER_ID:Clang>:-ftemplate-backtrace-limit=0>
$<$<CXX_COMPILER_ID:AppleClang>:-ftemplate-backtrace-limit=0>)
target_compile_options(pushmi INTERFACE
$<$<CXX_COMPILER_ID:Clang>:-stdlib=libc++>
$<$<CXX_COMPILER_ID:AppleClang>:-stdlib=libc++>)
if (PUSHMI_CONCEPTS)
target_compile_options(pushmi INTERFACE $<$<CXX_COMPILER_ID:GNU>:-fconcepts>)
endif ()
add_custom_target(buildSingleHeader
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/buildSingleHeader.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_dependencies(pushmi buildSingleHeader)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
DESTINATION include)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/external/executors-impl/include/
DESTINATION include/executors)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/external/futures-impl/future-executor-interaction/include/
DESTINATION include/futures)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/external/networking-ts-impl/include/
DESTINATION include/net)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/external/Catch2/
DESTINATION include/Catch2)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/external/nonius/include/
DESTINATION include/nonius)
install(TARGETS pushmi EXPORT pushmi-project)
install(EXPORT pushmi-project DESTINATION pushmi-project)
add_subdirectory(examples)
add_subdirectory(benchmarks)
enable_testing()
include(CTest)
add_subdirectory(test)
# Code of Conduct
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read the [full text](https://code.fb.com/codeofconduct/) so that you can understand what actions will and will not be tolerated.
# Contributing to pushmi
We want to make contributing to this project as easy and transparent as
possible.
## Our Development Process
All Development on this project is public.
## Pull Requests
We actively welcome your pull requests.
1. Fork the repo and create your branch from `master`.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation.
4. Ensure the test suite passes.
5. Make sure your code lints.
6. If you haven't already, complete the Contributor License Agreement ("CLA").
## Contributor License Agreement ("CLA")
In order to accept your pull request, we need you to submit a CLA. You only need
to do this once to work on any of Facebook's open source projects.
Complete your CLA here: <https://code.facebook.com/cla>
## Issues
We use GitHub issues to track public bugs. Please ensure your description is
clear and has sufficient instructions to be able to reproduce the issue.
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
disclosure of security bugs. In those cases, please go through the process
outlined on that page and do not file a public issue.
## Coding Style
* 2 spaces for indentation rather than tabs
* 80 character line length
## License
By contributing to pushmi, you agree that your contributions will be licensed
under the LICENSE file in the root directory of this source tree.
MIT License
Copyright (c) 2018-present, Facebook, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
FIND_PACKAGE (Boost)
if (Boost_FOUND)
add_executable(PushmiBenchmarks
runner.cpp
PushmiBenchmarks.cpp
)
target_include_directories(PushmiBenchmarks
PUBLIC ${Boost_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/../examples/include
)
target_link_libraries(PushmiBenchmarks
pushmi
Threads::Threads
)
else()
message(WARNING "Boost not found, no benchmarks will be built")
endif()
#include <vector>
#include "pushmi/o/just.h"
#include "pushmi/o/defer.h"
#include "pushmi/o/on.h"
#include "pushmi/o/transform.h"
#include "pushmi/o/tap.h"
#include "pushmi/o/via.h"
#include "pushmi/o/submit.h"
#include "pushmi/o/from.h"
#include "pushmi/o/for_each.h"
#include "pushmi/trampoline.h"
#include "pushmi/new_thread.h"
#include "pushmi/time_source.h"
#include "pushmi/receiver.h"
#include "pushmi/entangle.h"
#include "pool.h"
#include <folly/experimental/pushmi/o/just.h>
#include <folly/experimental/pushmi/o/defer.h>
#include <folly/experimental/pushmi/o/on.h>
#include <folly/experimental/pushmi/o/transform.h>
#include <folly/experimental/pushmi/o/tap.h>
#include <folly/experimental/pushmi/o/via.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/from.h>
#include <folly/experimental/pushmi/o/for_each.h>
#include <folly/experimental/pushmi/trampoline.h>
#include <folly/experimental/pushmi/new_thread.h>
#include <folly/experimental/pushmi/time_source.h>
#include <folly/experimental/pushmi/receiver.h>
#include <folly/experimental/pushmi/entangle.h>
#include <folly/experimental/pushmi/pool.h>
using namespace pushmi::aliases;
......
......@@ -11,9 +11,9 @@
#include <functional>
#include <utility>
#include "concepts.h"
#include "traits.h"
#include "detail/functional.h"
#include <folly/experimental/pushmi/concepts.h>
#include <folly/experimental/pushmi/traits.h>
#include <folly/experimental/pushmi/detail/functional.h>
namespace pushmi {
......@@ -63,6 +63,7 @@ struct ignoreVF {
};
struct abortEF {
[[noreturn]]
void operator()(detail::any) noexcept {
std::abort();
}
......
function(BuildSingleHeader HeaderName)
set(header_files ${ARGN})
# write out single-header
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/include/${HeaderName}-single-header.h" header)
string(APPEND incls "${header}")
foreach(f ${header_files})
message("processing ${f}")
file(READ ${f} contents)
string(REGEX REPLACE "(([\t ]*#[\t ]*pragma[\t ]+once)|([\t ]*#[\t ]*include))" "//\\1" filtered "${contents}")
string(APPEND incls "${filtered}")
endforeach()
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/include/${HeaderName}-single-footer.h" footer)
string(APPEND incls "${footer}")
file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/include/${HeaderName}.h "${incls}")
endfunction()
set(header_files
# keep in inclusion order
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/detail/if_constexpr.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/detail/concept_def.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/detail/functional.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/traits.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/detail/opt.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/forwards.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/entangle.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/properties.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/extension_points.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/concepts.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/boosters.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/piping.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/receiver.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/flow_receiver.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/executor.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/inline.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/trampoline.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/new_thread.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/strand.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/constrained_single_sender.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/time_single_sender.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/time_source.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/single_sender.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/flow_single_sender.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/many_sender.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/flow_many_sender.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/extension_operators.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/submit.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/subject.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/for_each.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/empty.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/from.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/just.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/error.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/defer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/on.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/tap.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/transform.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/filter.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/switch_on_error.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/via.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/request_via.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/pushmi/o/share.h"
)
BuildSingleHeader("pushmi" ${header_files})
......@@ -5,9 +5,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "forwards.h"
#include "extension_points.h"
#include "properties.h"
#include <folly/experimental/pushmi/forwards.h>
#include <folly/experimental/pushmi/extension_points.h>
#include <folly/experimental/pushmi/properties.h>
namespace pushmi {
......
......@@ -4,9 +4,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "receiver.h"
#include "executor.h"
#include "inline.h"
#include <folly/experimental/pushmi/receiver.h>
#include <folly/experimental/pushmi/executor.h>
#include <folly/experimental/pushmi/inline.h>
namespace pushmi {
......@@ -132,8 +132,8 @@ template<class SF, class ZF, class EXF>
// (requires Invocable<ZF&> && Invocable<EXF&> PUSHMI_BROKEN_SUBSUMPTION(&& not Sender<SF>))
class constrained_single_sender<SF, ZF, EXF> {
SF sf_;
EXF exf_;
ZF zf_;
EXF exf_;
public:
using properties = property_set<is_constrained<>, is_single<>>;
......@@ -165,8 +165,8 @@ template <PUSHMI_TYPE_CONSTRAINT(ConstrainedSender<is_single<>>) Data, class DSF
class constrained_single_sender<Data, DSF, DZF, DEXF> {
Data data_;
DSF sf_;
DEXF exf_;
DZF zf_;
DEXF exf_;
public:
using properties = property_set_insert_t<properties_t<Data>, property_set<is_single<>>>;
......
......@@ -275,14 +275,14 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
} \
}; \
}; \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr bool NAME = \
(bool)PUSHMI_PP_CAT(NAME, Concept)::Eval<PUSHMI_PP_EXPAND ARGS>{}; \
namespace lazy { \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr auto NAME = \
PUSHMI_PP_CAT(NAME, Concept)::Eval<PUSHMI_PP_EXPAND ARGS>{}; \
} \
PUSHMI_PP_CAT(PUSHMI_PP_DEF_, TPARAM) \
PUSHMI_INLINE_VAR constexpr bool NAME = \
(bool)PUSHMI_PP_CAT(NAME, Concept)::Eval<PUSHMI_PP_EXPAND ARGS>{} \
/**/
#endif
......@@ -410,11 +410,11 @@ PUSHMI_PP_IGNORE_CXX2A_COMPAT_BEGIN
#if __cpp_concepts
#define PUSHMI_PP_CONSTRAINED_USING(REQUIRES, NAME, ...) \
requires REQUIRES \
using NAME __VA_ARGS__; \
using NAME __VA_ARGS__ \
/**/
#else
#define PUSHMI_PP_CONSTRAINED_USING(REQUIRES, NAME, ...) \
using NAME std::enable_if_t<bool(REQUIRES), __VA_ARGS__>; \
using NAME std::enable_if_t<bool(REQUIRES), __VA_ARGS__> \
/**/
#endif
......@@ -515,7 +515,7 @@ constexpr auto expAnd(T0&& t0) {
return (T0&&)t0;
}
template<class T0, class... TN>
constexpr auto expAnd(T0&& t0, TN&&... tn) {
constexpr auto expAnd(T0&&, TN&&... tn) {
return concepts::detail::And<T0, decltype(isolated::expAnd((TN&&)tn...))>{};
}
......
......@@ -8,7 +8,7 @@
#include <functional>
#include "concept_def.h"
#include <folly/experimental/pushmi/detail/concept_def.h>
namespace pushmi {
......
......@@ -20,6 +20,54 @@
// If the statements could potentially be ill-formed, you can give some
// part of the expression a dependent type by wrapping it in `id`. For
/**
* Maybe_unused indicates that a function, variable or parameter might or
* might not be used, e.g.
*
* int foo(FOLLY_MAYBE_UNUSED int x) {
* #ifdef USE_X
* return x;
* #else
* return 0;
* #endif
* }
*/
#ifndef __has_attribute
#define PUSHMI_HAS_ATTRIBUTE(x) 0
#else
#define PUSHMI_HAS_ATTRIBUTE(x) __has_attribute(x)
#endif
#ifndef __has_cpp_attribute
#define PUSHMI_HAS_CPP_ATTRIBUTE(x) 0
#else
#define PUSHMI_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
#endif
#if PUSHMI_HAS_CPP_ATTRIBUTE(maybe_unused)
#define PUSHMI_MAYBE_UNUSED [[maybe_unused]]
#elif PUSHMI_HAS_ATTRIBUTE(__unused__) || __GNUC__
#define PUSHMI_MAYBE_UNUSED __attribute__((__unused__))
#else
#define PUSHMI_MAYBE_UNUSED
#endif
// disable buggy compatibility warning about "requires" and "concept" being
// C++20 keywords.
#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 5)
#define PUSHMI_PP_IGNORE_SHADOW_BEGIN \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wshadow\"") \
/**/
#define PUSHMI_PP_IGNORE_SHADOW_END \
_Pragma("GCC diagnostic pop")
#else
#define PUSHMI_PP_IGNORE_SHADOW_BEGIN
#define PUSHMI_PP_IGNORE_SHADOW_END
#endif
#define PUSHMI_COMMA ,
#define PUSHMI_EVAL(F, ...) F(__VA_ARGS__)
......@@ -47,7 +95,9 @@ struct id_fn {
else if constexpr PUSHMI_EVAL(PUSHMI_IF_CONSTEXPR_ELSE_, PUSHMI_IF_CONSTEXPR_IF_ LIST)
#define PUSHMI_IF_CONSTEXPR_RETURN(LIST)\
PUSHMI_PP_IGNORE_SHADOW_BEGIN \
PUSHMI_IF_CONSTEXPR(LIST)\
PUSHMI_PP_IGNORE_SHADOW_END \
/**/
#define PUSHMI_IF_CONSTEXPR_IF_(...) \
......@@ -79,7 +129,7 @@ struct id_fn {
/**/
#define PUSHMI_IF_CONSTEXPR_THEN_(...) \
([&](auto id)mutable->decltype(auto){__VA_ARGS__})) PUSHMI_COMMA \
([&](PUSHMI_MAYBE_UNUSED auto id)mutable->decltype(auto){__VA_ARGS__})) PUSHMI_COMMA \
/**/
#define PUSHMI_IF_CONSTEXPR_ELSE_(A, B) \
......@@ -87,7 +137,7 @@ struct id_fn {
/**/
#define PUSHMI_IF_CONSTEXPR_else(...) \
([&](auto id)mutable->decltype(auto){__VA_ARGS__});\
([&](PUSHMI_MAYBE_UNUSED auto id)mutable->decltype(auto){__VA_ARGS__});\
/**/
namespace pushmi {
......@@ -126,7 +176,7 @@ struct select<false> {
}
};
template <class T>
constexpr eat operator->*(T&& t) {
constexpr eat operator->*(T&&) {
return {};
}
};
......
......@@ -4,7 +4,7 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "forwards.h"
#include <folly/experimental/pushmi/forwards.h>
namespace pushmi {
......@@ -218,7 +218,7 @@ struct locked_entangled_pair : std::pair<T*, Dual*> {
locked_entangled_pair() = delete;
locked_entangled_pair(const locked_entangled_pair&) = delete;
locked_entangled_pair& operator=(const locked_entangled_pair&) = delete;
locked_entangled_pair(locked_entangled_pair&& o) : std::pair<T*, Dual*>(o), e(o.e) {o.e = nullptr;};
locked_entangled_pair(locked_entangled_pair&& o) : std::pair<T*, Dual*>(o), e(o.e) {o.e = nullptr;}
locked_entangled_pair& operator=(locked_entangled_pair&& o){
static_cast<std::pair<T*, Dual*>&>(*this) = static_cast<std::pair<T*, Dual*>&&>(o);
e = o.e;
......
add_library(examples INTERFACE)
target_include_directories(examples INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
add_subdirectory(twoway_execute)
add_subdirectory(then_execute)
add_subdirectory(composition)
add_subdirectory(for_each)
add_subdirectory(reduce)
add_subdirectory(set_done)
add_subdirectory(set_error)
......@@ -5,7 +5,7 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include <pushmi/single_sender.h>
#include <folly/experimental/pushmi/single_sender.h>
namespace pushmi {
......
add_executable(composition_2 composition_2.cpp)
target_link_libraries(composition_2
pushmi
examples
Threads::Threads)
add_executable(composition_3 composition_3.cpp)
target_link_libraries(composition_3
pushmi
examples
Threads::Threads)
add_executable(composition_4 composition_4.cpp)
target_link_libraries(composition_4
pushmi
examples
Threads::Threads)
\ No newline at end of file
......@@ -3,11 +3,11 @@
#include <cassert>
#include <iostream>
#include <pool.h>
#include <folly/experimental/pushmi/examples/pool.h>
#include <pushmi/o/transform.h>
#include <pushmi/o/via.h>
#include <pushmi/strand.h>
#include <folly/experimental/pushmi/o/transform.h>
#include <folly/experimental/pushmi/o/via.h>
#include <folly/experimental/pushmi/strand.h>
using namespace pushmi::aliases;
......
......@@ -3,11 +3,11 @@
#include <cassert>
#include <iostream>
#include <pushmi/o/defer.h>
#include <pushmi/o/share.h>
#include <folly/experimental/pushmi/o/defer.h>
#include <folly/experimental/pushmi/o/share.h>
#include <pushmi/o/just.h>
#include <pushmi/o/tap.h>
#include <folly/experimental/pushmi/o/just.h>
#include <folly/experimental/pushmi/o/tap.h>
// https://godbolt.org/g/rVLMTu
......
......@@ -3,14 +3,14 @@
#include <cassert>
#include <iostream>
#include <pool.h>
#include <folly/experimental/pushmi/examples/pool.h>
#include <pushmi/strand.h>
#include <folly/experimental/pushmi/strand.h>
#include <pushmi/o/request_via.h>
#include <folly/experimental/pushmi/o/request_via.h>
#include <pushmi/o/tap.h>
#include <pushmi/o/transform.h>
#include <folly/experimental/pushmi/o/tap.h>
#include <folly/experimental/pushmi/o/transform.h>
using namespace pushmi::aliases;
......
......@@ -5,9 +5,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include <bulk.h>
#include <pushmi/o/submit.h>
#include <pushmi/o/just.h>
#include <folly/experimental/pushmi/examples/bulk.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/just.h>
namespace pushmi {
......
add_executable(for_each_2 for_each_2.cpp)
target_link_libraries(for_each_2
pushmi
examples
Threads::Threads)
add_executable(for_each_3 for_each_3.cpp)
target_link_libraries(for_each_3
pushmi
examples
Threads::Threads)
......@@ -3,8 +3,8 @@
#include <cassert>
#include <iostream>
#include <pool.h>
#include <for_each.h>
#include <folly/experimental/pushmi/examples/pool.h>
#include <folly/experimental/pushmi/examples/for_each.h>
using namespace pushmi::aliases;
......
......@@ -3,7 +3,7 @@
#include <cassert>
#include <iostream>
#include <for_each.h>
#include <folly/experimental/pushmi/examples/for_each.h>
using namespace pushmi::aliases;
......
......@@ -4,8 +4,8 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include <pushmi/single_sender.h>
#include <pushmi/o/submit.h>
#include <folly/experimental/pushmi/single_sender.h>
#include <folly/experimental/pushmi/o/submit.h>
namespace pushmi {
......@@ -14,6 +14,7 @@ namespace detail {
struct no_fail_fn {
private:
struct on_error_impl {
[[noreturn]]
void operator()(any, any) noexcept {
std::abort();
}
......
......@@ -5,11 +5,11 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include <experimental/thread_pool>
#include <folly/experimental/thread_pool>
#include <pushmi/executor.h>
#include <pushmi/trampoline.h>
#include <pushmi/time_single_sender.h>
#include <folly/experimental/pushmi/executor.h>
#include <folly/experimental/pushmi/trampoline.h>
#include <folly/experimental/pushmi/time_single_sender.h>
#if __cpp_deduction_guides >= 201703
#define MAKE(x) x MAKE_
......
......@@ -5,9 +5,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include <bulk.h>
#include <pushmi/o/submit.h>
#include <pushmi/o/just.h>
#include <folly/experimental/pushmi/examples/bulk.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/just.h>
namespace pushmi {
......
add_executable(reduce_2 reduce_2.cpp)
target_link_libraries(reduce_2
pushmi
examples
Threads::Threads)
add_executable(reduce_3 reduce_3.cpp)
target_link_libraries(reduce_3
pushmi
examples
Threads::Threads)
\ No newline at end of file
......@@ -5,8 +5,8 @@
#include <iostream>
#include <exception>
#include <pool.h>
#include <reduce.h>
#include <folly/experimental/pushmi/examples/pool.h>
#include <folly/experimental/pushmi/examples/reduce.h>
using namespace pushmi::aliases;
......
......@@ -4,7 +4,7 @@
#include <iostream>
#include <exception>
#include <reduce.h>
#include <folly/experimental/pushmi/examples/reduce.h>
using namespace pushmi::aliases;
......@@ -40,4 +40,4 @@ int main()
assert(std::accumulate(vec.begin(), vec.end(), 2) == fortyTwo);
std::cout << "OK" << std::endl;
}
\ No newline at end of file
}
add_executable(set_done_2 set_done_2.cpp)
target_link_libraries(set_done_2
pushmi
examples
Threads::Threads)
......@@ -3,11 +3,11 @@
#include <cassert>
#include <iostream>
#include <pushmi/o/just.h>
#include <pushmi/o/tap.h>
#include <pushmi/o/filter.h>
#include <pushmi/o/transform.h>
#include <pushmi/o/empty.h>
#include <folly/experimental/pushmi/o/just.h>
#include <folly/experimental/pushmi/o/tap.h>
#include <folly/experimental/pushmi/o/filter.h>
#include <folly/experimental/pushmi/o/transform.h>
#include <folly/experimental/pushmi/o/empty.h>
using namespace pushmi::aliases;
......
add_executable(set_error_2 set_error_2.cpp)
target_link_libraries(set_error_2
pushmi
examples
Threads::Threads)
......@@ -3,12 +3,12 @@
#include <cassert>
#include <iostream>
#include <pushmi/o/just.h>
#include <pushmi/o/error.h>
#include <pushmi/o/empty.h>
#include <pushmi/o/transform.h>
#include <pushmi/o/switch_on_error.h>
#include <no_fail.h>
#include <folly/experimental/pushmi/o/just.h>
#include <folly/experimental/pushmi/o/error.h>
#include <folly/experimental/pushmi/o/empty.h>
#include <folly/experimental/pushmi/o/transform.h>
#include <folly/experimental/pushmi/o/switch_on_error.h>
#include <folly/experimental/pushmi/examples/no_fail.h>
using namespace pushmi::aliases;
......@@ -39,19 +39,19 @@ int main()
// transform an error
op::error(std::errc::argument_list_too_long) |
op::switch_on_error([](auto e) noexcept { return op::error(std::exception_ptr{}); }) |
op::switch_on_error([](auto) noexcept { return op::error(std::exception_ptr{}); }) |
op::submit(stop_abort);
// use default value if an error occurs
op::just(42) |
op::switch_on_error([](auto e) noexcept { return op::just(0); }) |
op::switch_on_error([](auto) noexcept { return op::just(0); }) |
op::submit();
// suppress if an error occurs
op::error(std::errc::argument_list_too_long) |
op::switch_on_error([](auto e) noexcept { return op::empty(); }) |
op::switch_on_error([](auto) noexcept { return op::empty(); }) |
op::submit();
// abort if an error occurs
......
add_executable(then_execute_2 then_execute_2.cpp)
target_link_libraries(then_execute_2
pushmi
examples
Threads::Threads)
\ No newline at end of file
......@@ -11,12 +11,12 @@
#include <futures.h>
#include <futures_static_thread_pool.h>
#include <pool.h>
#include <folly/experimental/pushmi/examples/pool.h>
#include <pushmi/strand.h>
#include <pushmi/o/just.h>
#include <pushmi/o/via.h>
#include <pushmi/o/transform.h>
#include <folly/experimental/pushmi/strand.h>
#include <folly/experimental/pushmi/o/just.h>
#include <folly/experimental/pushmi/o/via.h>
#include <folly/experimental/pushmi/o/transform.h>
using namespace pushmi::aliases;
......
add_executable(twoway_execute_2 twoway_execute_2.cpp)
target_link_libraries(twoway_execute_2
pushmi
examples
Threads::Threads)
\ No newline at end of file
......@@ -10,9 +10,9 @@
#include <functional>
#include <futures.h>
#include <pool.h>
#include <folly/experimental/pushmi/examples/pool.h>
#include <pushmi/o/transform.h>
#include <folly/experimental/pushmi/o/transform.h>
using namespace pushmi::aliases;
......
......@@ -6,7 +6,7 @@
#include <chrono>
#include <functional>
#include "receiver.h"
#include <folly/experimental/pushmi/receiver.h>
namespace pushmi {
namespace detail {
......
......@@ -7,8 +7,8 @@
#include <future>
#include <functional>
#include "traits.h"
#include "properties.h"
#include <folly/experimental/pushmi/traits.h>
#include <folly/experimental/pushmi/properties.h>
namespace pushmi {
namespace __adl {
......@@ -131,11 +131,11 @@ void submit(SD& sd, TP tp, Out out)
PUSHMI_TEMPLATE (class S)
(requires Invocable<S&>)
void set_done(S& s) noexcept {
void set_done(S&) noexcept {
}
PUSHMI_TEMPLATE (class S, class E)
(requires Invocable<S&>)
void set_error(S& s, E&& e) noexcept {
void set_error(S&, E&&) noexcept {
std::abort();
}
PUSHMI_TEMPLATE (class S)
......@@ -151,7 +151,7 @@ void set_value(S& s) noexcept(noexcept(s())) {
// std::promise does not support the done signal.
// either set_value or set_error must be called
template <class T>
void set_done(std::promise<T>& p) noexcept {}
void set_done(std::promise<T>&) noexcept {}
template <class T>
void set_error(std::promise<T>& p, std::exception_ptr e) noexcept {
......
......@@ -4,9 +4,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "flow_receiver.h"
#include "executor.h"
#include "trampoline.h"
#include <folly/experimental/pushmi/flow_receiver.h>
#include <folly/experimental/pushmi/executor.h>
#include <folly/experimental/pushmi/trampoline.h>
namespace pushmi {
......
......@@ -4,7 +4,7 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "receiver.h"
#include <folly/experimental/pushmi/receiver.h>
namespace pushmi {
......
......@@ -4,9 +4,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "flow_receiver.h"
#include "executor.h"
#include "trampoline.h"
#include <folly/experimental/pushmi/flow_receiver.h>
#include <folly/experimental/pushmi/executor.h>
#include <folly/experimental/pushmi/trampoline.h>
namespace pushmi {
......
......@@ -6,7 +6,7 @@
#include <exception>
#include <chrono>
#include "traits.h"
#include <folly/experimental/pushmi/traits.h>
namespace pushmi {
......@@ -100,12 +100,12 @@ class any_flow_receiver;
template<
class E = std::exception_ptr,
class... VN>
struct any_single_sender;
class any_single_sender;
template<
class E = std::exception_ptr,
class... VN>
struct any_many_sender;
class any_many_sender;
template <
class PE=std::exception_ptr,
......@@ -124,7 +124,7 @@ template<
class E = std::exception_ptr,
class C = std::ptrdiff_t,
class... VN>
struct any_constrained_single_sender;
class any_constrained_single_sender;
template<
class E = std::exception_ptr,
......
#pragma once
#ifndef PUSHMI_SINGLE_HEADER
#define PUSHMI_SINGLE_HEADER
// Copyright (c) 2018-present, Facebook, Inc.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include <cstddef>
#include <cassert>
#include <cstdint>
#include <cstdio>
#include <chrono>
#include <exception>
#include <functional>
#include <algorithm>
#include <utility>
#include <memory>
#include <type_traits>
#include <initializer_list>
#include <thread>
#include <future>
#include <tuple>
#include <deque>
#include <vector>
#include <queue>
#if __cpp_lib_optional >= 201606
#include <optional>
#endif
This diff is collapsed.
......@@ -4,7 +4,7 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "executor.h"
#include <folly/experimental/pushmi/executor.h>
namespace pushmi {
......
#!/usr/bin/env bash
TRUNK_VERSION="6.0.0"
set -e
# The pattern of clang --version is: clang version X.Y.Z (sometimes, see below).
COMPILER_VERSION_OUTPUT="$($CXX --version)"
arr=(${COMPILER_VERSION_OUTPUT// / })
COMPILER="${arr[0]}"
VERSION="${arr[2]}"
case $COMPILER in
"clang")
# Some Ubuntu clang builds are advertised as "just clang", but the
# Version still follows the pattern: 3.6.2-svn240577-1~exp1
# echo "Compiler is clang :)"
arr2=(${VERSION//-/ })
VERSION="${arr2[0]}"
;;
"Ubuntu")
# Ubuntu renames _some_ (not all) of its clang compilers, the pattern of
# clang --version is then:
# Ubuntu clang version 3.6.2-svn240577-1~exp1
COMPILER="${arr[1]}"
VERSION="${arr[3]}"
arr2=(${VERSION//-/ })
VERSION="${arr2[0]}"
;;
*)
echo "case did not match: compiler: ${COMPILER}"
exit 1
;;
esac
if [ ${COMPILER} != "clang" ]; then
echo "Error: trying to install libc++ for a compiler that is not clang: ${COMPILER}"
exit 1
fi
if [ -z ${VERSION+x} ]; then
echo "libc++ version is not set. To set the libc++ version: ./install_libcxx.sh -v X.Y.Z"
exit 4
fi
if [ ${VERSION} == $TRUNK_VERSION ]; then
echo "Fetching libc++ and libc++abi tip-of-trunk..."
# Checkout LLVM sources
git clone --depth=1 https://github.com/llvm-mirror/llvm.git llvm-source
git clone --depth=1 https://github.com/llvm-mirror/libcxx.git llvm-source/projects/libcxx
git clone --depth=1 https://github.com/llvm-mirror/libcxxabi.git llvm-source/projects/libcxxabi
else
echo "Fetching libc++/libc++abi version: ${VERSION}..."
LLVM_URL="http://releases.llvm.org/${VERSION}/llvm-${VERSION}.src.tar.xz"
LIBCXX_URL="http://releases.llvm.org/${VERSION}/libcxx-${VERSION}.src.tar.xz"
LIBCXXABI_URL="http://releases.llvm.org/${VERSION}/libcxxabi-${VERSION}.src.tar.xz"
curl -O $LLVM_URL
curl -O $LIBCXX_URL
curl -O $LIBCXXABI_URL
mkdir llvm-source
mkdir llvm-source/projects
mkdir llvm-source/projects/libcxx
mkdir llvm-source/projects/libcxxabi
tar -xf llvm-${VERSION}.src.tar.xz -C llvm-source --strip-components=1
tar -xf libcxx-${VERSION}.src.tar.xz -C llvm-source/projects/libcxx --strip-components=1
tar -xf libcxxabi-${VERSION}.src.tar.xz -C llvm-source/projects/libcxxabi --strip-components=1
fi
mkdir llvm-build
cd llvm-build
# - libc++ versions < 4.x do not have the install-cxxabi and install-cxx targets
# - only ASAN is enabled for clang/libc++ versions < 4.x
if [[ $VERSION == *"3."* ]]; then
cmake -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} \
-DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr \
../llvm-source
if [[ $SANITIZER == "Address;Undefined" ]]; then
ASAN_FLAGS="-fsanitize=address"
cmake -DCMAKE_CXX_FLAGS="${ASAN_FLAGS}" -DCMAKE_EXE_LINKER_FLAGS="${ASAN_FLAGS}" ../llvm-source
fi
make cxx -j2 VERBOSE=1
sudo cp -r lib/* /usr/lib/
sudo cp -r include/c++ /usr/include/
else
cmake -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} \
-DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr \
-DLIBCXX_ABI_UNSTABLE=ON \
-DLLVM_USE_SANITIZER=${SANITIZER} \
../llvm-source
make cxx -j2 VERBOSE=1
sudo make install-cxxabi install-cxx
fi
exit 0
......@@ -4,9 +4,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "receiver.h"
#include "executor.h"
#include "trampoline.h"
#include <folly/experimental/pushmi/receiver.h>
#include <folly/experimental/pushmi/executor.h>
#include <folly/experimental/pushmi/trampoline.h>
namespace pushmi {
......
......@@ -4,8 +4,8 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "executor.h"
#include "trampoline.h"
#include <folly/experimental/pushmi/executor.h>
#include <folly/experimental/pushmi/trampoline.h>
namespace pushmi {
......
......@@ -6,10 +6,10 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../receiver.h"
#include "../single_sender.h"
#include "submit.h"
#include "extension_operators.h"
#include <folly/experimental/pushmi/receiver.h>
#include <folly/experimental/pushmi/single_sender.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
namespace pushmi {
......
......@@ -6,9 +6,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../detail/functional.h"
#include "submit.h"
#include "extension_operators.h"
#include <folly/experimental/pushmi/detail/functional.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
namespace pushmi {
namespace detail {
......
......@@ -6,8 +6,8 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "submit.h"
#include "extension_operators.h"
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
namespace pushmi {
namespace detail {
......
......@@ -7,17 +7,17 @@
// LICENSE file in the root directory of this source tree.
#include <tuple>
#include "../piping.h"
#include "../boosters.h"
#include "../receiver.h"
#include "../flow_receiver.h"
#include "../single_sender.h"
#include "../many_sender.h"
#include "../time_single_sender.h"
#include "../flow_single_sender.h"
#include "../flow_many_sender.h"
#include "../detail/if_constexpr.h"
#include "../detail/functional.h"
#include <folly/experimental/pushmi/piping.h>
#include <folly/experimental/pushmi/boosters.h>
#include <folly/experimental/pushmi/receiver.h>
#include <folly/experimental/pushmi/flow_receiver.h>
#include <folly/experimental/pushmi/single_sender.h>
#include <folly/experimental/pushmi/many_sender.h>
#include <folly/experimental/pushmi/time_single_sender.h>
#include <folly/experimental/pushmi/flow_single_sender.h>
#include <folly/experimental/pushmi/flow_many_sender.h>
#include <folly/experimental/pushmi/detail/if_constexpr.h>
#include <folly/experimental/pushmi/detail/functional.h>
namespace pushmi {
......
......@@ -4,8 +4,8 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../piping.h"
#include "extension_operators.h"
#include <folly/experimental/pushmi/piping.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
namespace pushmi {
......
......@@ -4,8 +4,8 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "extension_operators.h"
#include "submit.h"
#include <folly/experimental/pushmi/o/extension_operators.h>
#include <folly/experimental/pushmi/o/submit.h>
namespace pushmi {
namespace detail {
......@@ -18,7 +18,7 @@ private:
struct Pull : Out {
explicit Pull(Out out) : Out(std::move(out)) {}
using properties = property_set_insert_t<properties_t<Out>, property_set<is_flow<>>>;
std::function<void(ptrdiff_t)> pull;
std::function<void(std::ptrdiff_t)> pull;
template<class V>
void value(V&& v) {
::pushmi::set_value(static_cast<Out&>(*this), (V&&) v);
......@@ -34,7 +34,7 @@ private:
}
PUSHMI_TEMPLATE(class Up)
(requires ReceiveValue<Up>)
void starting(Up up){}
void starting(Up){}
};
template <class... AN>
struct fn {
......
......@@ -4,11 +4,11 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../many_sender.h"
#include "../flow_many_sender.h"
#include "../trampoline.h"
#include "extension_operators.h"
#include "submit.h"
#include <folly/experimental/pushmi/many_sender.h>
#include <folly/experimental/pushmi/flow_many_sender.h>
#include <folly/experimental/pushmi/trampoline.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
#include <folly/experimental/pushmi/o/submit.h>
namespace pushmi {
......@@ -80,7 +80,7 @@ struct flow_from_up {
explicit flow_from_up(std::shared_ptr<Producer> p) : p(std::move(p)) {}
std::shared_ptr<Producer> p;
void value(ptrdiff_t requested) {
void value(std::ptrdiff_t requested) {
if (requested < 1) {return;}
// submit work to exec
::pushmi::submit(p->exec,
......@@ -101,7 +101,7 @@ struct flow_from_up {
}
template<class E>
void error(E e) noexcept {
void error(E) noexcept {
p->stop.store(true);
::pushmi::submit(p->exec,
make_receiver([p = p](auto) {
......@@ -132,7 +132,7 @@ private:
auto p = std::make_shared<Producer>(begin_, end_, std::move(out), exec_, false);
::pushmi::submit(exec_,
make_receiver([p](auto exec) {
make_receiver([p](auto) {
// pass reference for cancellation.
::pushmi::set_starting(p->out, make_receiver(flow_from_up<Producer>{p}));
}));
......
......@@ -6,9 +6,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../single_sender.h"
#include "submit.h"
#include "extension_operators.h"
#include <folly/experimental/pushmi/single_sender.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
namespace pushmi {
......
......@@ -4,9 +4,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../piping.h"
#include "../executor.h"
#include "extension_operators.h"
#include <folly/experimental/pushmi/piping.h>
#include <folly/experimental/pushmi/executor.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
namespace pushmi {
......
......@@ -6,10 +6,10 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../receiver.h"
#include "submit.h"
#include "extension_operators.h"
#include "via.h"
#include <folly/experimental/pushmi/receiver.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
#include <folly/experimental/pushmi/o/via.h>
namespace pushmi {
......
......@@ -6,11 +6,11 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../receiver.h"
#include "submit.h"
#include "extension_operators.h"
#include <folly/experimental/pushmi/receiver.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
#include "../subject.h"
#include <folly/experimental/pushmi/subject.h>
namespace pushmi {
......
......@@ -7,12 +7,12 @@
// LICENSE file in the root directory of this source tree.
#include <functional>
#include "../time_single_sender.h"
#include "../boosters.h"
#include "extension_operators.h"
#include "../trampoline.h"
#include "../detail/opt.h"
#include "../detail/if_constexpr.h"
#include <folly/experimental/pushmi/time_single_sender.h>
#include <folly/experimental/pushmi/boosters.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
#include <folly/experimental/pushmi/trampoline.h>
#include <folly/experimental/pushmi/detail/opt.h>
#include <folly/experimental/pushmi/detail/if_constexpr.h>
namespace pushmi {
namespace detail {
......@@ -56,7 +56,7 @@ private:
public:
template <class... AN>
auto operator()(AN&&... an) const {
return submit_fn::fn<AN...>{{(AN&&) an...}};
return submit_fn::fn<AN...>{std::tuple<AN...>{(AN&&) an...}};
}
};
......@@ -301,7 +301,7 @@ private:
public:
template <class... AN>
auto operator()(AN... an) const {
return blocking_submit_fn::fn<AN...>{{(AN&&) an...}};
return blocking_submit_fn::fn<AN...>{std::tuple<AN...>{(AN&&) an...}};
}
};
......
......@@ -4,8 +4,8 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../piping.h"
#include "extension_operators.h"
#include <folly/experimental/pushmi/piping.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
namespace pushmi {
......
......@@ -7,7 +7,7 @@
// LICENSE file in the root directory of this source tree.
#include <cassert>
#include "extension_operators.h"
#include <folly/experimental/pushmi/o/extension_operators.h>
namespace pushmi {
......@@ -103,7 +103,7 @@ private:
public:
template <class... AN>
auto operator()(AN... an) const {
return in_impl<AN...>{{std::move(an)...}};
return in_impl<AN...>{std::tuple<AN...>{std::move(an)...}};
}
};
......
......@@ -6,10 +6,10 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../receiver.h"
#include "../flow_receiver.h"
#include "submit.h"
#include "extension_operators.h"
#include <folly/experimental/pushmi/receiver.h>
#include <folly/experimental/pushmi/flow_receiver.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
namespace pushmi {
......
......@@ -4,9 +4,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "../piping.h"
#include "../executor.h"
#include "extension_operators.h"
#include <folly/experimental/pushmi/piping.h>
#include <folly/experimental/pushmi/executor.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
namespace pushmi {
......@@ -104,7 +104,7 @@ private:
struct executor_impl {
ExecutorFactory ef_;
template <class Data>
auto operator()(Data& data) const {
auto operator()(Data&) const {
return ef_();
}
};
......
......@@ -4,7 +4,7 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "traits.h"
#include <folly/experimental/pushmi/traits.h>
namespace pushmi {
......
......@@ -4,7 +4,7 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "traits.h"
#include <folly/experimental/pushmi/traits.h>
namespace pushmi {
......
......@@ -5,7 +5,7 @@
// LICENSE file in the root directory of this source tree.
#include <future>
#include "boosters.h"
#include <folly/experimental/pushmi/boosters.h>
namespace pushmi {
......
......@@ -4,9 +4,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "receiver.h"
#include "executor.h"
#include "trampoline.h"
#include <folly/experimental/pushmi/receiver.h>
#include <folly/experimental/pushmi/executor.h>
#include <folly/experimental/pushmi/trampoline.h>
namespace pushmi {
......
......@@ -4,8 +4,8 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "single_sender.h"
#include "executor.h"
#include <folly/experimental/pushmi/single_sender.h>
#include <folly/experimental/pushmi/executor.h>
#include <queue>
......
......@@ -7,8 +7,8 @@
#include <vector>
#include "time_single_sender.h"
#include "trampoline.h"
#include <folly/experimental/pushmi/time_single_sender.h>
#include <folly/experimental/pushmi/trampoline.h>
namespace pushmi {
......
add_library(catch STATIC catch.cpp)
target_include_directories(catch PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../external/Catch2/single_include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/Catch2>)
target_link_libraries(catch
pushmi)
include(../external/Catch2/contrib/Catch.cmake)
if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0" AND NOT PUSHMI_ONE_TEST_BINARY)
add_executable(FlowTest FlowTest.cpp)
target_link_libraries(FlowTest pushmi catch Threads::Threads)
catch_discover_tests(FlowTest)
add_executable(FlowManyTest FlowManyTest.cpp)
target_link_libraries(FlowManyTest pushmi catch Threads::Threads)
catch_discover_tests(FlowManyTest)
add_executable(CompileTest CompileTest.cpp)
target_link_libraries(CompileTest pushmi catch Threads::Threads)
# catch_discover_tests(CompileTest)
add_executable(NewThreadTest NewThreadTest.cpp)
target_link_libraries(NewThreadTest pushmi catch Threads::Threads)
catch_discover_tests(NewThreadTest)
add_executable(TrampolineTest TrampolineTest.cpp)
target_link_libraries(TrampolineTest pushmi catch Threads::Threads)
catch_discover_tests(TrampolineTest)
add_executable(PushmiTest PushmiTest.cpp)
target_link_libraries(PushmiTest pushmi catch Threads::Threads)
catch_discover_tests(PushmiTest)
else()
add_executable(PushmiTest PushmiTest.cpp
CompileTest.cpp
TrampolineTest.cpp
NewThreadTest.cpp
FlowTest.cpp
FlowManyTest.cpp
)
target_link_libraries(PushmiTest pushmi catch Threads::Threads)
catch_discover_tests(PushmiTest)
endif()
#include "catch.hpp"
#include <array>
......@@ -7,18 +6,20 @@
#include <chrono>
using namespace std::literals;
#include "pushmi/flow_many_sender.h"
#include "pushmi/o/submit.h"
#include "pushmi/o/from.h"
#include "pushmi/o/for_each.h"
#include <folly/experimental/pushmi/flow_many_sender.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/from.h>
#include <folly/experimental/pushmi/o/for_each.h>
#include "pushmi/entangle.h"
#include "pushmi/new_thread.h"
#include "pushmi/time_source.h"
#include "pushmi/trampoline.h"
#include <folly/experimental/pushmi/entangle.h>
#include <folly/experimental/pushmi/new_thread.h>
#include <folly/experimental/pushmi/time_source.h>
#include <folly/experimental/pushmi/trampoline.h>
using namespace pushmi::aliases;
#if 0
#if __cpp_deduction_guides >= 201703
#define MAKE(x) x MAKE_
#define MAKE_(...) \
......@@ -300,3 +301,4 @@ SCENARIO("flow many from", "[flow][sender][for_each]") {
}
}
}
#endif
#include "catch.hpp"
#include <type_traits>
#include <chrono>
using namespace std::literals;
#include "pushmi/flow_single_sender.h"
#include "pushmi/o/submit.h"
#include <folly/experimental/pushmi/flow_single_sender.h>
#include <folly/experimental/pushmi/o/submit.h>
#include "pushmi/entangle.h"
#include "pushmi/new_thread.h"
#include "pushmi/time_source.h"
#include "pushmi/trampoline.h"
#include <folly/experimental/pushmi/entangle.h>
#include <folly/experimental/pushmi/new_thread.h>
#include <folly/experimental/pushmi/time_source.h>
#include <folly/experimental/pushmi/trampoline.h>
using namespace pushmi::aliases;
#if 0
#if __cpp_deduction_guides >= 201703
#define MAKE(x) x MAKE_
#define MAKE_(...) \
......@@ -454,3 +455,4 @@ SCENARIO("flow single entangled cancellation new thread", "[flow][sender]") {
time.join();
}
}
#endif
#include "catch.hpp"
#include <type_traits>
#include <chrono>
using namespace std::literals;
#include "pushmi/flow_single_sender.h"
#include "pushmi/o/empty.h"
#include "pushmi/o/just.h"
#include "pushmi/o/on.h"
#include "pushmi/o/transform.h"
#include "pushmi/o/tap.h"
#include "pushmi/o/via.h"
#include "pushmi/o/submit.h"
#include "pushmi/o/extension_operators.h"
#include <folly/experimental/pushmi/flow_single_sender.h>
#include <folly/experimental/pushmi/o/empty.h>
#include <folly/experimental/pushmi/o/just.h>
#include <folly/experimental/pushmi/o/on.h>
#include <folly/experimental/pushmi/o/transform.h>
#include <folly/experimental/pushmi/o/tap.h>
#include <folly/experimental/pushmi/o/via.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
#include "pushmi/new_thread.h"
#include "pushmi/time_source.h"
#include "pushmi/strand.h"
#include <folly/experimental/pushmi/new_thread.h>
#include <folly/experimental/pushmi/time_source.h>
#include <folly/experimental/pushmi/strand.h>
using namespace pushmi::aliases;
#if 0
struct countdownsingle {
countdownsingle(int& c)
: counter(&c) {}
......@@ -204,3 +204,4 @@ SCENARIO( "new_thread executor", "[new_thread][sender]" ) {
time.join();
}
}
#endif
#include "catch.hpp"
#include <type_traits>
#include <chrono>
using namespace std::literals;
#include "pushmi/flow_single_sender.h"
#include "pushmi/o/empty.h"
#include "pushmi/o/from.h"
#include "pushmi/o/just.h"
#include "pushmi/o/on.h"
#include "pushmi/o/transform.h"
#include "pushmi/o/tap.h"
#include "pushmi/o/submit.h"
#include "pushmi/o/extension_operators.h"
#include <folly/experimental/pushmi/flow_single_sender.h>
#include <folly/experimental/pushmi/o/empty.h>
#include <folly/experimental/pushmi/o/from.h>
#include <folly/experimental/pushmi/o/just.h>
#include <folly/experimental/pushmi/o/on.h>
#include <folly/experimental/pushmi/o/transform.h>
#include <folly/experimental/pushmi/o/tap.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
#include "pushmi/trampoline.h"
#include "pushmi/new_thread.h"
#include <folly/experimental/pushmi/trampoline.h>
#include <folly/experimental/pushmi/new_thread.h>
using namespace pushmi::aliases;
#if 0
SCENARIO( "empty can be used with tap and submit", "[empty][sender]" ) {
GIVEN( "An empty sender" ) {
......@@ -151,3 +150,4 @@ SCENARIO( "from() can be used with transform and submit", "[from][sender]" ) {
}
}
#endif
#include "catch.hpp"
#include <type_traits>
#include <chrono>
using namespace std::literals;
#include "pushmi/flow_single_sender.h"
#include "pushmi/o/empty.h"
#include "pushmi/o/just.h"
#include "pushmi/o/on.h"
#include "pushmi/o/transform.h"
#include "pushmi/o/tap.h"
#include "pushmi/o/via.h"
#include "pushmi/o/submit.h"
#include "pushmi/o/extension_operators.h"
#include <folly/experimental/pushmi/flow_single_sender.h>
#include <folly/experimental/pushmi/o/empty.h>
#include <folly/experimental/pushmi/o/just.h>
#include <folly/experimental/pushmi/o/on.h>
#include <folly/experimental/pushmi/o/transform.h>
#include <folly/experimental/pushmi/o/tap.h>
#include <folly/experimental/pushmi/o/via.h>
#include <folly/experimental/pushmi/o/submit.h>
#include <folly/experimental/pushmi/o/extension_operators.h>
#include "pushmi/inline.h"
#include "pushmi/trampoline.h"
#include <folly/experimental/pushmi/inline.h>
#include <folly/experimental/pushmi/trampoline.h>
using namespace pushmi::aliases;
#if 0
struct countdownsingle {
countdownsingle(int& c)
: counter(&c) {}
......@@ -132,3 +132,4 @@ SCENARIO( "trampoline executor", "[trampoline][sender]" ) {
}
}
}
#endif
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
......@@ -4,10 +4,10 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "receiver.h"
#include "executor.h"
#include "inline.h"
#include "constrained_single_sender.h"
#include <folly/experimental/pushmi/receiver.h>
#include <folly/experimental/pushmi/executor.h>
#include <folly/experimental/pushmi/inline.h>
#include <folly/experimental/pushmi/constrained_single_sender.h>
namespace pushmi {
......
......@@ -4,8 +4,8 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#include "time_single_sender.h"
#include "executor.h"
#include <folly/experimental/pushmi/time_single_sender.h>
#include <folly/experimental/pushmi/executor.h>
#include <queue>
......@@ -467,7 +467,7 @@ private:
public:
time_source() : source_(std::make_shared<time_source_shared<E, time_point>>()) {
source_->start(source_);
};
}
PUSHMI_TEMPLATE(class NF, class ExecutorFactory)
(requires Invocable<ExecutorFactory&> && Executor<invoke_result_t<ExecutorFactory&>> && NeverBlocking<invoke_result_t<ExecutorFactory&>>)
......
......@@ -7,7 +7,7 @@
#include <functional>
#include <type_traits>
#include "detail/functional.h"
#include <folly/experimental/pushmi/detail/functional.h>
#define PUSHMI_NOEXCEPT_AUTO(...) \
noexcept(noexcept(static_cast<decltype((__VA_ARGS__))>(__VA_ARGS__)))\
......
......@@ -8,7 +8,7 @@
#include <chrono>
#include <deque>
#include <thread>
#include "executor.h"
#include <folly/experimental/pushmi/executor.h>
namespace pushmi {
......@@ -237,7 +237,8 @@ decltype(auto) repeat(delegator<E>& exec) {
::pushmi::submit(exec, recurse);
}
template <class AnyExec>
void repeat(AnyExec& exec) {
[[noreturn]]
void repeat(AnyExec&) {
std::abort();
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment