![]() |
|
|||
File indexing completed on 2025-06-30 08:06:35
0001 // Copyright 2018 The Abseil Authors. 0002 // 0003 // Licensed under the Apache License, Version 2.0 (the "License"); 0004 // you may not use this file except in compliance with the License. 0005 // You may obtain a copy of the License at 0006 // 0007 // https://www.apache.org/licenses/LICENSE-2.0 0008 // 0009 // Unless required by applicable law or agreed to in writing, software 0010 // distributed under the License is distributed on an "AS IS" BASIS, 0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0012 // See the License for the specific language governing permissions and 0013 // limitations under the License. 0014 // 0015 // ----------------------------------------------------------------------------- 0016 // File: bind_front.h 0017 // ----------------------------------------------------------------------------- 0018 // 0019 // `absl::bind_front()` returns a functor by binding a number of arguments to 0020 // the front of a provided (usually more generic) functor. Unlike `std::bind`, 0021 // it does not require the use of argument placeholders. The simpler syntax of 0022 // `absl::bind_front()` allows you to avoid known misuses with `std::bind()`. 0023 // 0024 // `absl::bind_front()` is meant as a drop-in replacement for C++20's upcoming 0025 // `std::bind_front()`, which similarly resolves these issues with 0026 // `std::bind()`. Both `bind_front()` alternatives, unlike `std::bind()`, allow 0027 // partial function application. (See 0028 // https://en.wikipedia.org/wiki/Partial_application). 0029 0030 #ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_ 0031 #define ABSL_FUNCTIONAL_BIND_FRONT_H_ 0032 0033 #if defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L 0034 #include <functional> // For std::bind_front. 0035 #endif // defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L 0036 0037 #include <utility> 0038 0039 #include "absl/functional/internal/front_binder.h" 0040 #include "absl/utility/utility.h" 0041 0042 namespace absl { 0043 ABSL_NAMESPACE_BEGIN 0044 0045 // bind_front() 0046 // 0047 // Binds the first N arguments of an invocable object and stores them by value. 0048 // 0049 // Like `std::bind()`, `absl::bind_front()` is implicitly convertible to 0050 // `std::function`. In particular, it may be used as a simpler replacement for 0051 // `std::bind()` in most cases, as it does not require placeholders to be 0052 // specified. More importantly, it provides more reliable correctness guarantees 0053 // than `std::bind()`; while `std::bind()` will silently ignore passing more 0054 // parameters than expected, for example, `absl::bind_front()` will report such 0055 // mis-uses as errors. In C++20, `absl::bind_front` is replaced by 0056 // `std::bind_front`. 0057 // 0058 // absl::bind_front(a...) can be seen as storing the results of 0059 // std::make_tuple(a...). 0060 // 0061 // Example: Binding a free function. 0062 // 0063 // int Minus(int a, int b) { return a - b; } 0064 // 0065 // assert(absl::bind_front(Minus)(3, 2) == 3 - 2); 0066 // assert(absl::bind_front(Minus, 3)(2) == 3 - 2); 0067 // assert(absl::bind_front(Minus, 3, 2)() == 3 - 2); 0068 // 0069 // Example: Binding a member function. 0070 // 0071 // struct Math { 0072 // int Double(int a) const { return 2 * a; } 0073 // }; 0074 // 0075 // Math math; 0076 // 0077 // assert(absl::bind_front(&Math::Double)(&math, 3) == 2 * 3); 0078 // // Stores a pointer to math inside the functor. 0079 // assert(absl::bind_front(&Math::Double, &math)(3) == 2 * 3); 0080 // // Stores a copy of math inside the functor. 0081 // assert(absl::bind_front(&Math::Double, math)(3) == 2 * 3); 0082 // // Stores std::unique_ptr<Math> inside the functor. 0083 // assert(absl::bind_front(&Math::Double, 0084 // std::unique_ptr<Math>(new Math))(3) == 2 * 3); 0085 // 0086 // Example: Using `absl::bind_front()`, instead of `std::bind()`, with 0087 // `std::function`. 0088 // 0089 // class FileReader { 0090 // public: 0091 // void ReadFileAsync(const std::string& filename, std::string* content, 0092 // const std::function<void()>& done) { 0093 // // Calls Executor::Schedule(std::function<void()>). 0094 // Executor::DefaultExecutor()->Schedule( 0095 // absl::bind_front(&FileReader::BlockingRead, this, 0096 // filename, content, done)); 0097 // } 0098 // 0099 // private: 0100 // void BlockingRead(const std::string& filename, std::string* content, 0101 // const std::function<void()>& done) { 0102 // CHECK_OK(file::GetContents(filename, content, {})); 0103 // done(); 0104 // } 0105 // }; 0106 // 0107 // `absl::bind_front()` stores bound arguments explicitly using the type passed 0108 // rather than implicitly based on the type accepted by its functor. 0109 // 0110 // Example: Binding arguments explicitly. 0111 // 0112 // void LogStringView(absl::string_view sv) { 0113 // LOG(INFO) << sv; 0114 // } 0115 // 0116 // Executor* e = Executor::DefaultExecutor(); 0117 // std::string s = "hello"; 0118 // absl::string_view sv = s; 0119 // 0120 // // absl::bind_front(LogStringView, arg) makes a copy of arg and stores it. 0121 // e->Schedule(absl::bind_front(LogStringView, sv)); // ERROR: dangling 0122 // // string_view. 0123 // 0124 // e->Schedule(absl::bind_front(LogStringView, s)); // OK: stores a copy of 0125 // // s. 0126 // 0127 // To store some of the arguments passed to `absl::bind_front()` by reference, 0128 // use std::ref()` and `std::cref()`. 0129 // 0130 // Example: Storing some of the bound arguments by reference. 0131 // 0132 // class Service { 0133 // public: 0134 // void Serve(const Request& req, std::function<void()>* done) { 0135 // // The request protocol buffer won't be deleted until done is called. 0136 // // It's safe to store a reference to it inside the functor. 0137 // Executor::DefaultExecutor()->Schedule( 0138 // absl::bind_front(&Service::BlockingServe, this, std::cref(req), 0139 // done)); 0140 // } 0141 // 0142 // private: 0143 // void BlockingServe(const Request& req, std::function<void()>* done); 0144 // }; 0145 // 0146 // Example: Storing bound arguments by reference. 0147 // 0148 // void Print(const std::string& a, const std::string& b) { 0149 // std::cerr << a << b; 0150 // } 0151 // 0152 // std::string hi = "Hello, "; 0153 // std::vector<std::string> names = {"Chuk", "Gek"}; 0154 // // Doesn't copy hi. 0155 // for_each(names.begin(), names.end(), 0156 // absl::bind_front(Print, std::ref(hi))); 0157 // 0158 // // DO NOT DO THIS: the functor may outlive "hi", resulting in 0159 // // dangling references. 0160 // foo->DoInFuture(absl::bind_front(Print, std::ref(hi), "Guest")); // BAD! 0161 // auto f = absl::bind_front(Print, std::ref(hi), "Guest"); // BAD! 0162 // 0163 // Example: Storing reference-like types. 0164 // 0165 // void Print(absl::string_view a, const std::string& b) { 0166 // std::cerr << a << b; 0167 // } 0168 // 0169 // std::string hi = "Hello, "; 0170 // // Copies "hi". 0171 // absl::bind_front(Print, hi)("Chuk"); 0172 // 0173 // // Compile error: std::reference_wrapper<const string> is not implicitly 0174 // // convertible to string_view. 0175 // // absl::bind_front(Print, std::cref(hi))("Chuk"); 0176 // 0177 // // Doesn't copy "hi". 0178 // absl::bind_front(Print, absl::string_view(hi))("Chuk"); 0179 // 0180 #if defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L 0181 using std::bind_front; 0182 #else // defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L 0183 template <class F, class... BoundArgs> 0184 constexpr functional_internal::bind_front_t<F, BoundArgs...> bind_front( 0185 F&& func, BoundArgs&&... args) { 0186 return functional_internal::bind_front_t<F, BoundArgs...>( 0187 absl::in_place, std::forward<F>(func), std::forward<BoundArgs>(args)...); 0188 } 0189 #endif // defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L 0190 0191 ABSL_NAMESPACE_END 0192 } // namespace absl 0193 0194 #endif // ABSL_FUNCTIONAL_BIND_FRONT_H_
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |