Skip to content
Open
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
1 change: 1 addition & 0 deletions .beman-tidy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
disabled_rules: []
ignored_paths:
- infra/
- include/beman/optional/detail/stl_interfaces/
13 changes: 8 additions & 5 deletions include/beman/inplace_vector/inplace_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#define BEMAN_INPLACE_VECTOR_INPLACE_VECTOR_HPP

#include <beman/inplace_vector/config.hpp>
#include <beman/optional/optional.hpp>

#include <algorithm> // for rotate...
#include <array>
Expand Down Expand Up @@ -327,18 +328,20 @@ struct inplace_vector_base : private storage::storage_for<T, N> {
return this->back();
}

template <class... Args> constexpr T *try_emplace_back(Args &&...args) {
template <class... Args>
constexpr beman::optional::optional<T &> try_emplace_back(Args &&...args) {
if (size() == capacity()) [[unlikely]]
return nullptr;
return &unchecked_emplace_back(std::forward<Args>(args)...);
return beman::optional::nullopt;
return beman::optional::optional<T &>(
unchecked_emplace_back(std::forward<Args>(args)...));
}

constexpr T *try_push_back(const T &x)
constexpr beman::optional::optional<T &> try_push_back(const T &x)
requires(std::constructible_from<T, const T &>)
{
return try_emplace_back(x);
}
constexpr T *try_push_back(T &&x)
constexpr beman::optional::optional<T &> try_push_back(T &&x)
requires(std::constructible_from<T, T &&>)
{
return try_emplace_back(std::forward<T &&>(x));
Expand Down
15 changes: 15 additions & 0 deletions include/beman/optional/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# include/beman/optional/CMakeLists.txt -*-cmake-*-
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

target_sources(
beman.optional
PUBLIC
FILE_SET beman_optional_headers
TYPE HEADERS
FILES
optional.hpp
detail/iterator.hpp
detail/stl_interfaces/config.hpp
detail/stl_interfaces/fwd.hpp
detail/stl_interfaces/iterator_interface.hpp
)
71 changes: 71 additions & 0 deletions include/beman/optional/detail/iterator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// include/beman/optional/detail/iterator.hpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef BEMAN_OPTIONAL_DETAIL_ITERATOR_HPP
#define BEMAN_OPTIONAL_DETAIL_ITERATOR_HPP

#include <beman/optional/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_OPTIONAL_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;
using typename base_type::pointer;
using typename base_type::reference;

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

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

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

private:
T *m_current;
};

} // namespace beman::optional::detail

#endif // BEMAN_OPTIONAL_DETAIL_ITERATOR_HPP
51 changes: 51 additions & 0 deletions include/beman/optional/detail/stl_interfaces/config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// include/beman/optional/detail/stl_interfaces/config.hpp -*-C++-*-

// 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_OPTIONAL_DETAIL_STL_INTERFACES_CONFIG_HPP
#define BEMAN_OPTIONAL_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_OPTIONAL_DETAIL_STL_INTERFACES_DISABLE_CONCEPTS)
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_USE_CONCEPTS 1
#else
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_USE_CONCEPTS 0
#endif

#if defined(__cpp_explicit_this_parameter) && \
BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_USE_CONCEPTS && \
!defined(BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_DISABLE_DEDUCED_THIS)
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS 1
#else
#define BEMAN_OPTIONAL_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_OPTIONAL_DETAIL_STL_INTERFACES_USE_CONCEPTS && \
!BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V1 inline namespace v1
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3
#elif BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_USE_CONCEPTS && \
!BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V2 inline namespace v2
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3
#else
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V3 inline namespace v3
#endif

#endif
85 changes: 85 additions & 0 deletions include/beman/optional/detail/stl_interfaces/fwd.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// include/beman/optional/detail/stl_interfaces/fwd.hpp -*-C++-*-

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy pasta?


// 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_OPTIONAL_DETAIL_STL_INTERFACES_FWD_HPP
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_FWD_HPP

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's weird that there's a detail include from optional here....

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so I think the issue here is we're introducing a dependence on beman optional -- is that right?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the original issue suggested using beman optional so i decided to go along with that
there's every chance i've mishandled bringing int the dependency


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

#ifndef BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_DOXYGEN

#if defined(_MSC_VER) || defined(__GNUC__) && __GNUC__ < 8
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NO_HIDDEN_FRIEND_CONSTEXPR
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR
#else
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR constexpr
#endif

#if defined(__GNUC__) && __GNUC__ < 9
#define BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_CONCEPT concept bool
#else
#define BEMAN_OPTIONAL_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_OPTIONAL_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