Repository navigation
use optional return types for fallible methods #152
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,3 +7,4 @@ | |
| disabled_rules: [] | ||
| ignored_paths: | ||
| - infra/ | ||
| - include/beman/optional/detail/stl_interfaces/ | ||
| 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 | ||
| ) |
| 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 |
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| // include/beman/optional/detail/stl_interfaces/fwd.hpp -*-C++-*- | ||
|
|
||
| // 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> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's weird that there's a detail include from optional here....
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
|
|
||
| #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 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy pasta?