1 // Copyright (c) 2021 Marshall A. Greenblatt. Portions copyright (c) 2021
2 // Google Inc. All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the name Chromium Embedded
15 // Framework nor the names of its contributors may be used to endorse
16 // or promote products derived from this software without specific prior
17 // written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 //
31
32 #ifndef CEF_INCLUDE_BASE_CEF_CXX17_BACKPORTS_H_
33 #define CEF_INCLUDE_BASE_CEF_CXX17_BACKPORTS_H_
34 #pragma once
35
36 #if defined(USING_CHROMIUM_INCLUDES)
37 // When building CEF include the Chromium header directly.
38 // TODO(cef): Change to "base/cxx17_backports.h" in M93.
39 #include "base/stl_util.h"
40 #else // !USING_CHROMIUM_INCLUDES
41 // The following is substantially similar to the Chromium implementation.
42 // If the Chromium implementation diverges the below implementation should be
43 // updated to match.
44
45 #include <array>
46 #include <initializer_list>
47 #include <memory>
48 #include <string>
49
50 namespace base {
51
52 // C++14 implementation of C++17's std::size():
53 // http://en.cppreference.com/w/cpp/iterator/size
54 template <typename Container>
55 constexpr auto size(const Container& c) -> decltype(c.size()) {
56 return c.size();
57 }
58
59 template <typename T, size_t N>
size(const T (& array)[N])60 constexpr size_t size(const T (&array)[N]) noexcept {
61 return N;
62 }
63
64 // C++14 implementation of C++17's std::empty():
65 // http://en.cppreference.com/w/cpp/iterator/empty
66 template <typename Container>
67 constexpr auto empty(const Container& c) -> decltype(c.empty()) {
68 return c.empty();
69 }
70
71 template <typename T, size_t N>
empty(const T (& array)[N])72 constexpr bool empty(const T (&array)[N]) noexcept {
73 return false;
74 }
75
76 template <typename T>
empty(std::initializer_list<T> il)77 constexpr bool empty(std::initializer_list<T> il) noexcept {
78 return il.size() == 0;
79 }
80
81 // C++14 implementation of C++17's std::data():
82 // http://en.cppreference.com/w/cpp/iterator/data
83 template <typename Container>
84 constexpr auto data(Container& c) -> decltype(c.data()) {
85 return c.data();
86 }
87
88 // std::basic_string::data() had no mutable overload prior to C++17 [1].
89 // Hence this overload is provided.
90 // Note: str[0] is safe even for empty strings, as they are guaranteed to be
91 // null-terminated [2].
92 //
93 // [1] http://en.cppreference.com/w/cpp/string/basic_string/data
94 // [2] http://en.cppreference.com/w/cpp/string/basic_string/operator_at
95 template <typename CharT, typename Traits, typename Allocator>
data(std::basic_string<CharT,Traits,Allocator> & str)96 CharT* data(std::basic_string<CharT, Traits, Allocator>& str) {
97 return std::addressof(str[0]);
98 }
99
100 template <typename Container>
101 constexpr auto data(const Container& c) -> decltype(c.data()) {
102 return c.data();
103 }
104
105 template <typename T, size_t N>
data(T (& array)[N])106 constexpr T* data(T (&array)[N]) noexcept {
107 return array;
108 }
109
110 template <typename T>
data(std::initializer_list<T> il)111 constexpr const T* data(std::initializer_list<T> il) noexcept {
112 return il.begin();
113 }
114
115 // std::array::data() was not constexpr prior to C++17 [1].
116 // Hence these overloads are provided.
117 //
118 // [1] https://en.cppreference.com/w/cpp/container/array/data
119 template <typename T, size_t N>
data(std::array<T,N> & array)120 constexpr T* data(std::array<T, N>& array) noexcept {
121 return !array.empty() ? &array[0] : nullptr;
122 }
123
124 template <typename T, size_t N>
data(const std::array<T,N> & array)125 constexpr const T* data(const std::array<T, N>& array) noexcept {
126 return !array.empty() ? &array[0] : nullptr;
127 }
128
129 } // namespace base
130
131 #endif // !USING_CHROMIUM_INCLUDES
132
133 #endif // CEF_INCLUDE_BASE_CEF_CXX17_BACKPORTS_H_
134