Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P3168R1: use a non-pointer iterator type #18

Merged
merged 17 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from 11 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
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# /CMakeLists.txt -*-makefile-*-
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

cmake_minimum_required(VERSION 3.10)

project(beman_optional26 VERSION 0.0.0 LANGUAGES CXX)
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#! /usr/bin/make -f
# -*-makefile-*-
# /Makefile -*-makefile-*-
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

INSTALL_PREFIX?=.install/
PROJECT?=$(shell basename $(CURDIR))
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# Beman.Optional26: C++26 Extensions for std::optional

<!--
SPDX-License-Identifier: 2.0 license with LLVM exceptions
-->

This implementation incorporates the C++26 extensions added for `std::optional`. The `Beman.Optional26` library aims to evaluate the stability, the usability, and the performance of these proposed changes before they are officially adopted by WG21 into the C++ Working Draft. Additionally, it allows developers to use these new features before they are implemented in major standard library compilers.

**Implements**:
* [`std::optional<T&>` (P2988R5)](https://wg21.link/P2988R5)
* [Give *std::optional* Range Support (P3168R1)](https://wg21.link/P3168R1).

## License

Source is licensed with the Apache 2.0 license with LLVM exceptions

Expand Down
3 changes: 3 additions & 0 deletions cmake/Config.cmake.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# cmake/Config.cmake.in -*-makefile-*-
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
Expand Down
2 changes: 1 addition & 1 deletion etc/gcc-flags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include_guard(GLOBAL)
set(CMAKE_CXX_STANDARD 23)

set(CMAKE_CXX_FLAGS
"-Wall -Wextra "
"-std=c++23 -Wall -Wextra "
CACHE STRING "CXX_FLAGS" FORCE)

set(CMAKE_CXX_FLAGS_DEBUG "-O0 -fno-inline -g3" CACHE STRING "C++ DEBUG Flags" FORCE)
Expand Down
3 changes: 3 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# examples/CMakeLists.txt -*-makefile-*-
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

set(BEMAN_OPTIONAL26_LIBRARY "beman_optional26")

include(GNUInstallDirs)
Expand Down
19 changes: 19 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
# Beman.Optional26 Examples

<!--
SPDX-License-Identifier: 2.0 license with LLVM exceptions
-->

List of usage examples for `Beman.Optional26`.

## License
Source is licensed with the Apache 2.0 license with LLVM exceptions

// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

Documentation and associated papers are licensed with the Creative Commons Attribution 4.0 International license.

// SPDX-License-Identifier: CC-BY-4.0

The intent is that the source and documentation are available for use by people implementing their own optional types as well as people using the optional presented here as-is.

The README itself is licesed with CC0 1.0 Universal. Copy the contents and incorporate in your own work as you see fit.

// SPDX-License-Identifier: CC0-1.0

## Sample

Check [sample](sample.cpp) for basic `Beman.Optional26` library usage.
Expand Down
3 changes: 3 additions & 0 deletions examples/optional_ref.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// examples/optional_ref.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <Beman/Optional26/optional.hpp>

#include <string>
Expand Down
3 changes: 3 additions & 0 deletions examples/range_loop.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// examples/range_loop.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <Beman/Optional26/optional.hpp>
#include <iostream>

Expand Down
3 changes: 3 additions & 0 deletions examples/sample.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// examples/sample.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <Beman/Optional26/optional.hpp>
#include <iostream>

Expand Down
3 changes: 3 additions & 0 deletions extern/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# extern/CMakeLists.txt -*-makefile-*-
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

add_subdirectory(googletest EXCLUDE_FROM_ALL)
73 changes: 73 additions & 0 deletions include/Beman/Optional26/detail/iterator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// include/Beman/Optional26/detail/iterator.hpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef BEMAN_OPTIONAL26_DETAIL_ITERATOR_HPP
#define BEMAN_OPTIONAL26_DETAIL_ITERATOR_HPP

#include <Beman/Optional26/detail/stl_interfaces/iterator_interface.hpp>

#include <concepts>
#include <iterator>

namespace beman::optional::detail {

// Forward declaration.
template <class T, class Container>
struct contiguous_iterator;

// Base class for contiguous iterator types with Boost stl_interfaces library.
// Current implementation based on P2727R4: std::iterator_interface.
template <class T, class Container>
using base_contiguous_iterator = stl_interfaces::iterator_interface<
#if !BEMAN_OPTIONAL26_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
contiguous_iterator<T, Container>, // Required for P2727R4 to work with C++20/C++23. TODO: Do more experiments.
#endif
std::contiguous_iterator_tag,
T>;

// This is a minimal contiguous iterator. It uses stl_interfaces library from Boost
// (current implementation based on https://wg21.link/P2727R4).
//
// TODO: Change this to use the stl_interfaces library from Beman if/when available.
//
// @tparam T - The type of the elements the iterator points to.
// @tparam Container - The type of the container the iterator points to. This parameter exists solely so that different
// containers using this template can instantiate different types, even if the T parameter is the same.
template <class T, class Container>
struct contiguous_iterator : public base_contiguous_iterator<T, Container> {
// Alias for the base class.
using base_type = base_contiguous_iterator<T, Container>;
// Alias for types from the base class.
using typename base_type::difference_type;
neatudarius marked this conversation as resolved.
Show resolved Hide resolved
using typename base_type::iterator_category;
using typename base_type::iterator_concept;
using typename base_type::pointer;
using typename base_type::reference;
using typename base_type::value_type;

// Default constructor.
contiguous_iterator() noexcept : m_current() {}

// Pointer to iterator constructor.
contiguous_iterator(pointer it) noexcept : m_current(it) {}

// As per P2727R4, for contiguous iterator we only need to provide operator*, operator+= and operator-.
reference operator*() const noexcept { return *m_current; }
auto& operator+=(difference_type pos) noexcept {
m_current += pos;
return *this;
}
difference_type operator-(contiguous_iterator other) const noexcept { return m_current - other.m_current; }

private:
T* m_current;
};

// Check concepts for the contiguous_iterator class.
neatudarius marked this conversation as resolved.
Show resolved Hide resolved
// Test here with Container=int[]/const int[]. More tests can be found in iterator.t.cpp.
static_assert(std::contiguous_iterator<contiguous_iterator<int, int[]>>);
static_assert(std::contiguous_iterator<contiguous_iterator<const int, const int[]>>);

} // namespace beman::optional::detail

#endif // BEMAN_OPTIONAL26_DETAIL_ITERATOR_HPP
49 changes: 49 additions & 0 deletions include/Beman/Optional26/detail/stl_interfaces/config.hpp
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/Optional26/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/Optional26/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::optional::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::optional::detail

#endif
Loading
Loading