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 <type_traits>
17
18#include "pw_polyfill/standard_library/namespace.h"
19
20_PW_POLYFILL_BEGIN_NAMESPACE_STD
21
22template <class InputIterator, class OutputIterator>
23constexpr OutputIterator copy(InputIterator first,
24                              InputIterator last,
25                              OutputIterator dest) {
26  while (first != last) {
27    *dest++ = *first++;
28  }
29  return dest;
30}
31
32template <typename T>
33constexpr const T& min(const T& lhs, const T& rhs) {
34  return (rhs < lhs) ? rhs : lhs;
35}
36
37template <typename T>
38constexpr const T& max(const T& lhs, const T& rhs) {
39  return (lhs < rhs) ? rhs : lhs;
40}
41
42template <class InputIterator, typename T>
43constexpr InputIterator find(InputIterator first,
44                             InputIterator last,
45                             const T& value) {
46  for (; first != last; ++first) {
47    if (*first == value) {
48      return first;
49    }
50  }
51  return last;
52}
53
54template <typename T>
55constexpr T&& forward(remove_reference_t<T>& value) {
56  return static_cast<T&&>(value);
57}
58
59template <typename T>
60constexpr T&& forward(remove_reference_t<T>&& value) {
61  return static_cast<T&&>(value);
62}
63
64template <class LhsIterator, class RhsIterator>
65constexpr bool equal(LhsIterator first_l,
66                     LhsIterator last_l,
67                     RhsIterator first_r,
68                     RhsIterator last_r) {
69  while (first_l != last_l && first_r != last_r) {
70    if (*first_l != *first_r) {
71      return false;
72    }
73    ++first_l;
74    ++first_r;
75  }
76  return first_l == last_l && first_r == last_r;
77}
78
79template <class LhsIterator, class RhsIterator>
80constexpr bool lexicographical_compare(LhsIterator first_l,
81                                       LhsIterator last_l,
82                                       RhsIterator first_r,
83                                       RhsIterator last_r) {
84  while (first_l != last_l && first_r != last_r) {
85    if (*first_l < *first_r) {
86      return true;
87    }
88    if (*first_r < *first_l) {
89      return false;
90    }
91
92    ++first_l;
93    ++first_r;
94  }
95  return (first_l == last_l) && (first_r != last_r);
96}
97
98_PW_POLYFILL_END_NAMESPACE_STD
99