Skip to content

Commit

Permalink
Add stl_interfaces fallback when deducing this is unavailable.
Browse files Browse the repository at this point in the history
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 beman-project#10 and depends on beman-project#12.
  • Loading branch information
camio committed Oct 18, 2024
1 parent 5b6c36e commit 843054c
Show file tree
Hide file tree
Showing 9 changed files with 1,192 additions and 24 deletions.
14 changes: 12 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,20 @@ include(CompilerFeatureTest)

beman_iterator26_check_deducing_this(COMPILER_SUPPORTS_DEDUCING_THIS)

if(NOT COMPILER_SUPPORTS_DEDUCING_THIS)
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.")
option(BEMAN_ITERATOR_INTERFACE26_USE_DEDUCING_THIS
"Make use of deducing this. Turn this off for non-conforming compilers."
${COMPILER_SUPPORTS_DEDUCING_THIS})

if(BEMAN_ITERATOR_INTERFACE26_USE_DEDUCING_THIS AND NOT COMPILER_SUPPORTS_DEDUCING_THIS)
message(WARNING "Building with deducing this support despite of the compiler's lack of support for it")
endif()

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

enable_testing()

set(TARGETS_EXPORT_NAME ${CMAKE_PROJECT_NAME}Targets)
Expand Down
6 changes: 6 additions & 0 deletions include/beman/iterator_interface26/config.hpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef BEMAN_ITERATOR_INTERFACE26_CONFIG_HPP
#define BEMAN_ITERATOR_INTERFACE26_CONFIG_HPP

#cmakedefine01 BEMAN_ITERATOR_INTERFACE26_USE_DEDUCING_THIS()

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// include/beman/optional26/detail/stl_interfaces/config.hpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// Copyright (C) 2020 T. Zachary Laine
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_CONFIG_HPP
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_CONFIG_HPP

// Included for definition of __cpp_lib_concepts.
#include <iterator>

#if defined(__cpp_lib_concepts) && defined(__cpp_lib_ranges) && \
!defined(BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_DISABLE_CONCEPTS)
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS 1
#else
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS 0
#endif

#if defined(__cpp_explicit_this_parameter) && BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS && \
!defined(BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_DISABLE_DEDUCED_THIS)
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS 1
#else
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS 0
#endif

// The inline namespaces v1, v2, and v3 represent C++14, C++20, and C++23 and
// later, respectively. v1 is inline for standards before C++20, and v2 is
// inline for C++20 and later. Note that this only applies to code for which
// multiple vI namespace alternatives exist. For example, some instances of
// the v1 namespace may still be inline, if there is no v2 version of its
// contents.
#if !BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS && !BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V1 inline namespace v1
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3
#elif BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS && !BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V2 inline namespace v2
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3
#else
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V3 inline namespace v3
#endif

#endif
88 changes: 88 additions & 0 deletions include/beman/iterator_interface26/detail/stl_interfaces/fwd.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// include/beman/optional26/detail/stl_interfaces/fwd.hpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// Copyright (C) 2019 T. Zachary Laine
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_FWD_HPP
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_FWD_HPP

#include <beman/iterator_interface26/detail/stl_interfaces/config.hpp>

#if BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_CONCEPTS
#include <ranges>
#endif
#if defined(__cpp_lib_three_way_comparison)
#include <compare>
#endif

#ifndef BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_DOXYGEN

#if defined(_MSC_VER) || defined(__GNUC__) && __GNUC__ < 8
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NO_HIDDEN_FRIEND_CONSTEXPR
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR
#else
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR constexpr
#endif

#if defined(__GNUC__) && __GNUC__ < 9
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_CONCEPT concept bool
#else
#define BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_CONCEPT concept
#endif

#endif

namespace beman::iterator_interface26::detail {
namespace stl_interfaces {

/** An enumeration used to indicate whether the underlying data have a
contiguous or discontiguous layout when instantiating `view_interface`
and `sequence_container_interface`. */
enum class element_layout : bool { discontiguous = false, contiguous = true };

BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_NAMESPACE_V1 {

namespace v1_dtl {
template <typename... T>
using void_t = void;

template <typename Iter>
using iter_difference_t = typename std::iterator_traits<Iter>::difference_type;

template <typename Range, typename = void>
struct iterator;
template <typename Range>
struct iterator<Range, void_t<decltype(std::declval<Range&>().begin())>> {
using type = decltype(std::declval<Range&>().begin());
};
template <typename Range>
using iterator_t = typename iterator<Range>::type;

template <typename Range, typename = void>
struct sentinel;
template <typename Range>
struct sentinel<Range, void_t<decltype(std::declval<Range&>().end())>> {
using type = decltype(std::declval<Range&>().end());
};
template <typename Range>
using sentinel_t = typename sentinel<Range>::type;

template <typename Range>
using range_difference_t = iter_difference_t<iterator_t<Range>>;

template <typename Range>
using common_range = std::is_same<iterator_t<Range>, sentinel_t<Range>>;

template <typename Range, typename = void>
struct decrementable_sentinel : std::false_type {};
template <typename Range>
struct decrementable_sentinel<Range, void_t<decltype(--std::declval<sentinel_t<Range>&>())>> : std::true_type {};
} // namespace v1_dtl
}
} // namespace stl_interfaces
} // namespace beman::optional26::detail

#endif
Loading

0 comments on commit 843054c

Please sign in to comment.