Skip to content

Commit 843054c

Browse files
committed
Add stl_interfaces fallback when deducing this is unavailable.
Added a build option, BEMAN_ITERATOR_INTERFACE26_USE_DEDUCING_THIS, that switches between the deducing this implementation and that used by stl_interfaces. It defaults to whether the compiler supports deducing this. This element of configuration is placed in a generated config.hpp. This was chosen, as opposed to using a define passed as a compiler flag, to avoid ODR violations with larger projects with incoherent flag usage. The `iterator_interface_access` struct was moved to its own header since it is needed by both the deducing this and stl_interfaces implementations. The stl_interfaces implementation was modifed to use this so it better conforms to the paper. Some cleanup is still needed before this gets merged in: - There are optional26 remnants where stl_interfaces was brought in from. - Documentation is needed to explain when the extra template parameter is required. BEMAN_ITERATOR_INTERFACE26_USE_DEDUCING_THIS() should probably also be mentioned in that context. The intent is to address these once the overall approach has consensus. Fixes bemanproject#10 and depends on bemanproject#12.
1 parent 5b6c36e commit 843054c

File tree

9 files changed

+1192
-24
lines changed

9 files changed

+1192
-24
lines changed

CMakeLists.txt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,20 @@ include(CompilerFeatureTest)
88

99
beman_iterator26_check_deducing_this(COMPILER_SUPPORTS_DEDUCING_THIS)
1010

11-
if(NOT COMPILER_SUPPORTS_DEDUCING_THIS)
12-
message(FATAL_ERROR "The selected compiler and flags lack C++23's deducing this support, which is required to build this project. Try adding -DCMAKE_CXX_STANDARD=23 to your command line parameters and, failing that, upgrade your compiler.")
11+
option(BEMAN_ITERATOR_INTERFACE26_USE_DEDUCING_THIS
12+
"Make use of deducing this. Turn this off for non-conforming compilers."
13+
${COMPILER_SUPPORTS_DEDUCING_THIS})
14+
15+
if(BEMAN_ITERATOR_INTERFACE26_USE_DEDUCING_THIS AND NOT COMPILER_SUPPORTS_DEDUCING_THIS)
16+
message(WARNING "Building with deducing this support despite of the compiler's lack of support for it")
1317
endif()
1418

19+
configure_file(
20+
"${PROJECT_SOURCE_DIR}/include/beman/iterator_interface26/config.hpp.in"
21+
"${PROJECT_BINARY_DIR}/include/beman/iterator_interface26/config.hpp"
22+
@ONLY
23+
)
24+
1525
enable_testing()
1626

1727
set(TARGETS_EXPORT_NAME ${CMAKE_PROJECT_NAME}Targets)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef BEMAN_ITERATOR_INTERFACE26_CONFIG_HPP
2+
#define BEMAN_ITERATOR_INTERFACE26_CONFIG_HPP
3+
4+
#cmakedefine01 BEMAN_ITERATOR_INTERFACE26_USE_DEDUCING_THIS()
5+
6+
#endif
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// include/beman/optional26/detail/stl_interfaces/config.hpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
// Copyright (C) 2020 T. Zachary Laine
5+
//
6+
// Distributed under the Boost Software License, Version 1.0. (See
7+
// accompanying file LICENSE_1_0.txt or copy at
8+
// http://www.boost.org/LICENSE_1_0.txt)
9+
#ifndef BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_CONFIG_HPP
10+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_CONFIG_HPP
11+
12+
// Included for definition of __cpp_lib_concepts.
13+
#include <iterator>
14+
15+
#if defined(__cpp_lib_concepts) && defined(__cpp_lib_ranges) && \
16+
!defined(BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_DISABLE_CONCEPTS)
17+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS 1
18+
#else
19+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS 0
20+
#endif
21+
22+
#if defined(__cpp_explicit_this_parameter) && BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS && \
23+
!defined(BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_DISABLE_DEDUCED_THIS)
24+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS 1
25+
#else
26+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS 0
27+
#endif
28+
29+
// The inline namespaces v1, v2, and v3 represent C++14, C++20, and C++23 and
30+
// later, respectively. v1 is inline for standards before C++20, and v2 is
31+
// inline for C++20 and later. Note that this only applies to code for which
32+
// multiple vI namespace alternatives exist. For example, some instances of
33+
// the v1 namespace may still be inline, if there is no v2 version of its
34+
// contents.
35+
#if !BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS && !BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
36+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V1 inline namespace v1
37+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2
38+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3
39+
#elif BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS && !BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
40+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1
41+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V2 inline namespace v2
42+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3
43+
#else
44+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1
45+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2
46+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V3 inline namespace v3
47+
#endif
48+
49+
#endif
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// include/beman/optional26/detail/stl_interfaces/fwd.hpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
// Copyright (C) 2019 T. Zachary Laine
5+
//
6+
// Distributed under the Boost Software License, Version 1.0. (See
7+
// accompanying file LICENSE_1_0.txt or copy at
8+
// http://www.boost.org/LICENSE_1_0.txt)
9+
#ifndef BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_FWD_HPP
10+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_FWD_HPP
11+
12+
#include <beman/iterator_interface26/detail/stl_interfaces/config.hpp>
13+
14+
#if BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS
15+
#include <ranges>
16+
#endif
17+
#if defined(__cpp_lib_three_way_comparison)
18+
#include <compare>
19+
#endif
20+
21+
#ifndef BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_DOXYGEN
22+
23+
#if defined(_MSC_VER) || defined(__GNUC__) && __GNUC__ < 8
24+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NO_HIDDEN_FRIEND_CONSTEXPR
25+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR
26+
#else
27+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR constexpr
28+
#endif
29+
30+
#if defined(__GNUC__) && __GNUC__ < 9
31+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_CONCEPT concept bool
32+
#else
33+
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_CONCEPT concept
34+
#endif
35+
36+
#endif
37+
38+
namespace beman::iterator_interface26::detail {
39+
namespace stl_interfaces {
40+
41+
/** An enumeration used to indicate whether the underlying data have a
42+
contiguous or discontiguous layout when instantiating `view_interface`
43+
and `sequence_container_interface`. */
44+
enum class element_layout : bool { discontiguous = false, contiguous = true };
45+
46+
BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V1 {
47+
48+
namespace v1_dtl {
49+
template <typename... T>
50+
using void_t = void;
51+
52+
template <typename Iter>
53+
using iter_difference_t = typename std::iterator_traits<Iter>::difference_type;
54+
55+
template <typename Range, typename = void>
56+
struct iterator;
57+
template <typename Range>
58+
struct iterator<Range, void_t<decltype(std::declval<Range&>().begin())>> {
59+
using type = decltype(std::declval<Range&>().begin());
60+
};
61+
template <typename Range>
62+
using iterator_t = typename iterator<Range>::type;
63+
64+
template <typename Range, typename = void>
65+
struct sentinel;
66+
template <typename Range>
67+
struct sentinel<Range, void_t<decltype(std::declval<Range&>().end())>> {
68+
using type = decltype(std::declval<Range&>().end());
69+
};
70+
template <typename Range>
71+
using sentinel_t = typename sentinel<Range>::type;
72+
73+
template <typename Range>
74+
using range_difference_t = iter_difference_t<iterator_t<Range>>;
75+
76+
template <typename Range>
77+
using common_range = std::is_same<iterator_t<Range>, sentinel_t<Range>>;
78+
79+
template <typename Range, typename = void>
80+
struct decrementable_sentinel : std::false_type {};
81+
template <typename Range>
82+
struct decrementable_sentinel<Range, void_t<decltype(--std::declval<sentinel_t<Range>&>())>> : std::true_type {};
83+
} // namespace v1_dtl
84+
}
85+
} // namespace stl_interfaces
86+
} // namespace beman::optional26::detail
87+
88+
#endif

0 commit comments

Comments
 (0)