1// Copyright 2020 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include <cstddef>
17
18#include "pw_polyfill/standard.h"
19#include "pw_polyfill/standard_library/namespace.h"
20
21_PW_POLYFILL_BEGIN_NAMESPACE_STD
22
23#define __cpp_lib_nonmember_container_access 201411L
24
25template <typename C>
26auto begin(C& container) -> decltype(container.begin()) {
27  return container.begin();
28}
29
30template <typename C>
31auto begin(const C& container) -> decltype(container.begin()) {
32  return container.begin();
33}
34
35template <typename C>
36constexpr auto data(C& container) -> decltype(container.data()) {
37  return container.data();
38}
39
40template <typename C>
41constexpr auto data(const C& container) -> decltype(container.data()) {
42  return container.data();
43}
44
45template <typename T, decltype(sizeof(0)) kSize>
46constexpr T* data(T (&array)[kSize]) noexcept {
47  return array;
48}
49
50template <typename C>
51auto end(C& container) -> decltype(container.end()) {
52  return container.end();
53}
54
55template <typename C>
56auto end(const C& container) -> decltype(container.end()) {
57  return container.end();
58}
59
60template <typename C>
61constexpr auto size(const C& container) -> decltype(container.size()) {
62  return container.size();
63}
64
65template <typename T, decltype(sizeof(0)) kSize>
66constexpr decltype(sizeof(0)) size(const T (&)[kSize]) noexcept {
67  return kSize;
68}
69
70// NOT IMPLEMENTED: iterator_traits does not work
71template <typename>
72struct iterator_traits {};
73
74struct input_iterator_tag {};
75struct output_iterator_tag {};
76struct forward_iterator_tag : public input_iterator_tag {};
77struct bidirectional_iterator_tag : public forward_iterator_tag {};
78struct random_access_iterator_tag : public bidirectional_iterator_tag {};
79#if PW_CXX_STANDARD_IS_SUPPORTED(20)
80struct contiguous_iterator_tag : public random_access_iterator_tag {};
81#endif  // PW_CXX_STANDARD_IS_SUPPORTED(20)
82
83// NOT IMPLEMENTED: Reverse iterators are not implemented.
84template <typename>
85struct reverse_iterator;
86
87_PW_POLYFILL_END_NAMESPACE_STD
88