Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
173
TMessagesProj/jni/voip/webrtc/base/containers/checked_range.h
Normal file
173
TMessagesProj/jni/voip/webrtc/base/containers/checked_range.h
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#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 {
|
||||
|
||||
// CheckedContiguousRange is a light-weight wrapper around a container modeling
|
||||
// the ContiguousContainer requirement [1, 2]. Effectively this means that the
|
||||
// container stores its elements contiguous in memory. Furthermore, it is
|
||||
// expected that base::data(container) and base::size(container) are valid
|
||||
// expressions, and that data() + idx is dereferenceable for all idx in the
|
||||
// range [0, size()). In the standard library this includes the containers
|
||||
// std::string, std::vector and std::array, but other containers like
|
||||
// std::initializer_list and C arrays are supported as well.
|
||||
//
|
||||
// In general this class is in nature quite similar to base::span, and its API
|
||||
// is inspired by it. Similarly to base::span (and other view-like containers
|
||||
// such as base::StringPiece) callers are encouraged to pass checked ranges by
|
||||
// value.
|
||||
//
|
||||
// However, one important difference is that this class stores a pointer to the
|
||||
// underlying container (as opposed to just storing its data() and size()), and
|
||||
// thus is able to deal with changes to the container, such as removing or
|
||||
// adding elements.
|
||||
//
|
||||
// Note however that this class still does not extend the life-time of the
|
||||
// underlying container, and thus callers need to make sure that the container
|
||||
// outlives the view to avoid dangling pointers and references.
|
||||
//
|
||||
// Lastly, this class leverages base::CheckedContiguousIterator to perform
|
||||
// bounds CHECKs, causing program termination when e.g. dereferencing the end
|
||||
// iterator.
|
||||
//
|
||||
// [1] https://en.cppreference.com/w/cpp/named_req/ContiguousContainer
|
||||
// [2]
|
||||
// https://eel.is/c++draft/container.requirements.general#def:contiguous_container
|
||||
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.");
|
||||
|
||||
// Required for converting constructor below.
|
||||
template <typename Container>
|
||||
friend class CheckedContiguousRange;
|
||||
|
||||
// Default constructor. Behaves as if the underlying container was empty.
|
||||
constexpr CheckedContiguousRange() noexcept = default;
|
||||
|
||||
// Templated constructor restricted to possibly cvref qualified versions of
|
||||
// ContiguousContainer. This makes sure it does not shadow the auto generated
|
||||
// copy and move constructors.
|
||||
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) {}
|
||||
|
||||
// Converting constructor allowing conversions like CCR<C> to CCR<const C>,
|
||||
// but disallowing CCR<const C> to CCR<C> or CCR<Derived[]> to CCR<Base[]>,
|
||||
// which are unsafe. Furthermore, this is the same condition as used by the
|
||||
// converting constructors of std::span<T> and std::unique_ptr<T[]>.
|
||||
// See https://wg21.link/n4042 for details.
|
||||
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;
|
||||
};
|
||||
|
||||
// Utility functions helping to create const ranges and performing automatic
|
||||
// type deduction.
|
||||
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));
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_CONTAINERS_CHECKED_RANGE_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue