123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #ifndef BASE_CONTAINERS_CHECKED_RANGE_H_
- #define BASE_CONTAINERS_CHECKED_RANGE_H_
- #include <stddef.h>
- #include <iterator>
- #include <type_traits>
- #include "base/containers/checked_iterators.h"
- #include "base/stl_util.h"
- namespace base {
- template <typename ContiguousContainer>
- class CheckedContiguousRange {
- public:
- using element_type = std::remove_pointer_t<decltype(
- base::data(std::declval<ContiguousContainer&>()))>;
- using value_type = std::remove_cv_t<element_type>;
- using reference = element_type&;
- using const_reference = const element_type&;
- using pointer = element_type*;
- using const_pointer = const element_type*;
- using iterator = CheckedContiguousIterator<element_type>;
- using const_iterator = CheckedContiguousConstIterator<element_type>;
- using reverse_iterator = std::reverse_iterator<iterator>;
- using const_reverse_iterator = std::reverse_iterator<const_iterator>;
- using difference_type = typename iterator::difference_type;
- using size_type = size_t;
- static_assert(!std::is_reference<ContiguousContainer>::value,
- "Error: ContiguousContainer can not be a reference.");
-
- template <typename Container>
- friend class CheckedContiguousRange;
-
- constexpr CheckedContiguousRange() noexcept = default;
-
-
-
- template <int&... ExplicitArgumentBarrier,
- typename Container,
- typename = std::enable_if_t<std::is_same<
- std::remove_cv_t<std::remove_reference_t<ContiguousContainer>>,
- std::remove_cv_t<std::remove_reference_t<Container>>>::value>>
- constexpr CheckedContiguousRange(Container&& container) noexcept
- : container_(&container) {}
-
-
-
-
-
- template <int&... ExplicitArgumentBarrier,
- typename Container,
- typename = std::enable_if_t<std::is_convertible<
- typename CheckedContiguousRange<Container>::element_type (*)[],
- element_type (*)[]>::value>>
- constexpr CheckedContiguousRange(
- CheckedContiguousRange<Container> range) noexcept
- : container_(range.container_) {}
- constexpr iterator begin() const noexcept {
- return iterator(data(), data(), data() + size());
- }
- constexpr iterator end() const noexcept {
- return iterator(data(), data() + size(), data() + size());
- }
- constexpr const_iterator cbegin() const noexcept { return begin(); }
- constexpr const_iterator cend() const noexcept { return end(); }
- constexpr reverse_iterator rbegin() const noexcept {
- return reverse_iterator(end());
- }
- constexpr reverse_iterator rend() const noexcept {
- return reverse_iterator(begin());
- }
- constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
- constexpr const_reverse_iterator crend() const noexcept { return rend(); }
- constexpr reference front() const noexcept { return *begin(); }
- constexpr reference back() const noexcept { return *(end() - 1); }
- constexpr reference operator[](size_type idx) const noexcept {
- return *(begin() + idx);
- }
- constexpr pointer data() const noexcept {
- return container_ ? base::data(*container_) : nullptr;
- }
- constexpr const_pointer cdata() const noexcept { return data(); }
- constexpr size_type size() const noexcept {
- return container_ ? base::size(*container_) : 0;
- }
- constexpr bool empty() const noexcept {
- return container_ ? base::empty(*container_) : true;
- }
- private:
- ContiguousContainer* container_ = nullptr;
- };
- template <typename ContiguousContainer>
- using CheckedContiguousConstRange =
- CheckedContiguousRange<const ContiguousContainer>;
- template <int&... ExplicitArgumentBarrier, typename ContiguousContainer>
- constexpr auto MakeCheckedContiguousRange(
- ContiguousContainer&& container) noexcept {
- return CheckedContiguousRange<std::remove_reference_t<ContiguousContainer>>(
- std::forward<ContiguousContainer>(container));
- }
- template <int&... ExplicitArgumentBarrier, typename ContiguousContainer>
- constexpr auto MakeCheckedContiguousConstRange(
- ContiguousContainer&& container) noexcept {
- return CheckedContiguousConstRange<
- std::remove_reference_t<ContiguousContainer>>(
- std::forward<ContiguousContainer>(container));
- }
- }
- #endif
|