Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
"tests": [
"Debug.Default", "Release.Default", "Release.TSan",
"Release.MaxSan", "Debug.Werror", "Debug.Dynamic",
"Debug.Coverage"
"Debug.Coverage", "Debug.-DBEMAN_TAKE_BEFORE_USE_MODULES=On"
]
}
]
Expand Down Expand Up @@ -82,7 +82,7 @@ jobs:
{ "stdlibs": ["libstdc++", "libc++"],
"tests": [
"Debug.Default", "Release.Default", "Release.TSan",
"Release.MaxSan", "Debug.Werror", "Debug.Dynamic"
"Release.MaxSan", "Debug.Werror", "Debug.Dynamic", "Debug.-DBEMAN_TAKE_BEFORE_USE_MODULES=On"
]
}
]
Expand Down
59 changes: 49 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

cmake_minimum_required(VERSION 3.30...4.3)

include(infra/cmake/enable-experimental-import-std.cmake)

project(
beman.take_before
DESCRIPTION "take_before_view"
Expand All @@ -24,21 +26,58 @@ option(
)

# for find of beman_install_library and configure_build_telemetry
option(
BEMAN_TAKE_BEFORE_USE_MODULES
"Provide beman.take_before as a C++ module"
OFF
)

if(BEMAN_TAKE_BEFORE_USE_MODULES)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
endif()

configure_file(
"${PROJECT_SOURCE_DIR}/include/beman/take_before/config_generated.hpp.in"
"${PROJECT_BINARY_DIR}/include/beman/take_before/config_generated.hpp"
@ONLY
)

include(infra/cmake/beman-install-library.cmake)
include(infra/cmake/BuildTelemetryConfig.cmake)

add_library(beman.take_before INTERFACE)
if(BEMAN_TAKE_BEFORE_USE_MODULES)
add_library(beman.take_before STATIC)
else()
add_library(beman.take_before INTERFACE)
endif()
add_library(beman::take_before ALIAS beman.take_before)

target_sources(
beman.take_before
PUBLIC FILE_SET HEADERS BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include"
)

set_target_properties(
beman.take_before
PROPERTIES VERIFY_INTERFACE_HEADER_SETS ${PROJECT_IS_TOP_LEVEL}
)
if(BEMAN_TAKE_BEFORE_USE_MODULES)
target_sources(
beman.take_before
PUBLIC
FILE_SET CXX_MODULES
FILE_SET HEADERS
BASE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_BINARY_DIR}/include"
)
set_target_properties(beman.take_before PROPERTIES CXX_MODULE_STD ON)
target_compile_features(beman.take_before PUBLIC cxx_std_23)
else()
target_sources(
beman.take_before
PUBLIC
FILE_SET HEADERS
BASE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_BINARY_DIR}/include"
)
set_target_properties(
beman.take_before
PROPERTIES VERIFY_INTERFACE_HEADER_SETS ${PROJECT_IS_TOP_LEVEL}
)
endif()

add_subdirectory(include/beman/take_before)

Expand Down
3 changes: 3 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ foreach(example ${ALL_EXAMPLES})
add_executable(${example})
target_sources(${example} PRIVATE ${example}.cpp)
target_link_libraries(${example} PRIVATE beman::take_before)
if(BEMAN_TAKE_BEFORE_USE_MODULES)
set_target_properties(${example} PROPERTIES CXX_MODULE_STD ON)
endif()
endforeach()
18 changes: 14 additions & 4 deletions examples/take_before_compose.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// examples/take_before_compose.cpp

#include <beman/take_before/take_before.hpp>
#include <beman/take_before/config.hpp>

#if BEMAN_TAKE_BEFORE_USE_MODULES()

import std;

#else

#include <iostream>
#include <ranges>
#include <vector>
#include <iostream>
#include <ranges>
#include <vector>

#endif

#include <beman/take_before/take_before.hpp>

namespace btb = beman::take_before;

Expand Down
16 changes: 13 additions & 3 deletions examples/take_before_direct_usage.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// examples/take_before_direct_usage.cpp

#include <beman/take_before/take_before.hpp>
#include <beman/take_before/config.hpp>

#if BEMAN_TAKE_BEFORE_USE_MODULES()

import std;

#else

#include <iostream>
#include <vector>
#include <iostream>
#include <vector>

#endif

#include <beman/take_before/take_before.hpp>

namespace btb = beman::take_before;

Expand Down
13 changes: 12 additions & 1 deletion examples/take_before_ntbs.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// examples/take_before_ntbs.cpp

#include <beman/take_before/config.hpp>

#if BEMAN_TAKE_BEFORE_USE_MODULES()

import std;

#else

#include <iostream>

#endif

#include <beman/take_before/take_before.hpp>
#include <iostream>

namespace btb = beman::take_before;

Expand Down
22 changes: 16 additions & 6 deletions examples/take_before_text_split.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,23 @@
// This example demonstrates the usage of beman::take_before in a range-printer.
// Requires: range support (C++20).

#include <beman/take_before/take_before.hpp>
#include <beman/take_before/config.hpp>

#if BEMAN_TAKE_BEFORE_USE_MODULES()

import std;

#else

#include <algorithm>
#include <iostream>
#include <ranges>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <ranges>
#include <string>
#include <vector>

#endif

#include <beman/take_before/take_before.hpp>

namespace btb = beman::take_before;

Expand Down
23 changes: 22 additions & 1 deletion include/beman/take_before/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

target_sources(beman.take_before PUBLIC FILE_SET HEADERS FILES take_before.hpp)
if(BEMAN_TAKE_BEFORE_USE_MODULES)
target_sources(
beman.take_before
PUBLIC
FILE_SET CXX_MODULES FILES take_before.cppm
FILE_SET HEADERS
FILES
config.hpp
take_before.hpp
"${PROJECT_BINARY_DIR}/include/beman/take_before/config_generated.hpp"
)
else()
target_sources(
beman.take_before
PUBLIC
FILE_SET HEADERS
FILES
config.hpp
take_before.hpp
"${PROJECT_BINARY_DIR}/include/beman/take_before/config_generated.hpp"
)
endif()
12 changes: 12 additions & 0 deletions include/beman/take_before/config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef BEMAN_TAKE_BEFORE_CONFIG_HPP
#define BEMAN_TAKE_BEFORE_CONFIG_HPP

#if !defined(__has_include) || __has_include(<beman/take_before/config_generated.hpp>)
#include <beman/take_before/config_generated.hpp>
#else
#define BEMAN_TAKE_BEFORE_USE_MODULES() 0
#endif

#endif
8 changes: 8 additions & 0 deletions include/beman/take_before/config_generated.hpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef BEMAN_TAKE_BEFORE_CONFIG_GENERATED_HPP
#define BEMAN_TAKE_BEFORE_CONFIG_GENERATED_HPP

#cmakedefine01 BEMAN_TAKE_BEFORE_USE_MODULES()

#endif
11 changes: 11 additions & 0 deletions include/beman/take_before/take_before.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export module beman.take_before;

import std;

#define BEMAN_TAKE_BEFORE_INCLUDED_FROM_INTERFACE_UNIT
export {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winclude-angled-in-module-purview"
#include <beman/take_before/take_before.hpp>
#pragma clang diagnostic pop
}
51 changes: 34 additions & 17 deletions include/beman/take_before/take_before.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,27 @@
#ifndef BEMAN_TAKE_BEFORE_TAKE_BEFORE_HPP
#define BEMAN_TAKE_BEFORE_TAKE_BEFORE_HPP

#include <algorithm>
#include <concepts>
#include <memory>
#include <optional>
#include <ranges>
#include <type_traits>
#include <utility>

// clang-format off
#include <beman/take_before/config.hpp>

#if BEMAN_TAKE_BEFORE_USE_MODULES() && !defined(BEMAN_TAKE_BEFORE_INCLUDED_FROM_INTERFACE_UNIT)

import beman.take_before;

#else

#if !BEMAN_TAKE_BEFORE_USE_MODULES()

#include <algorithm>
#include <concepts>
#include <memory>
#include <optional>
#include <ranges>
#include <type_traits>
#include <utility>

#endif // !BEMAN_TAKE_BEFORE_USE_MODULES()

// clang-format off
#if __cpp_concepts > 202002L
#error "C++20 concepts is required"
#endif
Expand All @@ -30,8 +42,8 @@ using maybe_const = std::conditional_t<Const, const T, T>;
// [range.utility.helpers] simple-view - exposition only
template <class R>
concept simple_view = std::ranges::view<R> && std::ranges::range<const R> &&
std::same_as<std::ranges::iterator_t<R>, std::ranges::iterator_t<const R>> &&
std::same_as<std::ranges::sentinel_t<R>, std::ranges::sentinel_t<const R>>;
std::same_as<std::ranges::iterator_t<R>, std::ranges::iterator_t<const R> > &&
std::same_as<std::ranges::sentinel_t<R>, std::ranges::sentinel_t<const R> >;

// ============================================================================
// tidy-obj concept for borrowed range optimization
Expand All @@ -53,7 +65,7 @@ using movable_box = std::optional<T>;
template <std::ranges::view V, std::move_constructible T>
requires std::ranges::input_range<V> && std::is_object_v<T> &&
std::indirect_binary_predicate<std::ranges::equal_to, std::ranges::iterator_t<V>, const T*>
class take_before_view : public std::ranges::view_interface<take_before_view<V, T>> {
class take_before_view : public std::ranges::view_interface<take_before_view<V, T> > {
template <bool>
class sentinel; // exposition only

Expand Down Expand Up @@ -143,7 +155,7 @@ class take_before_view<V, T>::sentinel {
sentinel() = default;

constexpr sentinel(sentinel<!Const> s)
requires Const && std::convertible_to<std::ranges::sentinel_t<V>, std::ranges::sentinel_t<Base>>
requires Const && std::convertible_to<std::ranges::sentinel_t<V>, std::ranges::sentinel_t<Base> >
: end_(std::move(s.end_)) {
if constexpr (!tidy_obj<T>) {
value_ = s.value_;
Expand All @@ -161,8 +173,10 @@ class take_before_view<V, T>::sentinel {
}

template <bool OtherConst = !Const>
requires std::sentinel_for<std::ranges::sentinel_t<Base>, std::ranges::iterator_t<maybe_const<OtherConst, V>>>
friend constexpr bool operator==(const std::ranges::iterator_t<maybe_const<OtherConst, V>>& x, const sentinel& y) {
requires std::sentinel_for<std::ranges::sentinel_t<Base>,
std::ranges::iterator_t<maybe_const<OtherConst, V> > >
friend constexpr bool operator==(const std::ranges::iterator_t<maybe_const<OtherConst, V> >& x,
const sentinel& y) {
if constexpr (tidy_obj<T>) {
return y.end_ == x || T() == *x;
} else {
Expand All @@ -183,7 +197,7 @@ take_before_view(R&&, T) -> take_before_view<std::ranges::views::all_t<R>, T>;

namespace std::ranges {
template <class V, class T>
constexpr bool enable_borrowed_range<beman::take_before::take_before_view<V, T>> =
constexpr bool enable_borrowed_range<beman::take_before::take_before_view<V, T> > =
enable_borrowed_range<V> && beman::take_before::tidy_obj<T>;
} // namespace std::ranges

Expand Down Expand Up @@ -241,12 +255,15 @@ struct take_before_fn {
// Overload 3: single argument for pipe operator
template <typename T>
constexpr auto operator()(T&& value) const {
return detail::take_before_closure<std::decay_t<T>>(std::forward<T>(value));
return detail::take_before_closure<std::decay_t<T> >(std::forward<T>(value));
}
};

inline constexpr take_before_fn take_before;

} // namespace beman::take_before::views

#endif // #if BEMAN_TAKE_BEFORE_USE_MODULES() &&
// !defined(BEMAN_TAKE_BEFORE_INCLUDED_FROM_INTERFACE_UNIT)

#endif // BEMAN_TAKE_BEFORE_TAKE_BEFORE_HPP
Loading
Loading