1 // Copyright 2018 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://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, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_COMPLEX_OPTION_H 16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_COMPLEX_OPTION_H 17 18 #include "google/cloud/storage/version.h" 19 #include "absl/types/optional.h" 20 #include <iostream> 21 22 namespace google { 23 namespace cloud { 24 namespace storage { 25 inline namespace STORAGE_CLIENT_NS { 26 namespace internal { 27 /** 28 * A complex option is a request optional parameter that is neither a header 29 * nor a query parameter. 30 * 31 * The majority of the request options either change a header (or group of 32 * headers) or they set a query parameter. They are modeled using 33 * `WellKnownParameter` or `WellKnownHeader`. A few options do neither, they 34 * affect how the query is performed. Notably, we provide options where the 35 * user can provide pre-computed values for the MD5 hash and CRC32C values of 36 * an upload or download. 37 * 38 * @tparam Derived the type we will use to represent the option. 39 * @tparam T the C++ type of the option value. 40 */ 41 template <typename Derived, typename T> 42 class ComplexOption { 43 public: ComplexOption()44 ComplexOption() : value_{} {} ComplexOption(T value)45 explicit ComplexOption(T value) : value_(std::move(value)) {} 46 option_name()47 char const* option_name() const { return Derived::name(); } has_value()48 bool has_value() const { return value_.has_value(); } value()49 T const& value() const { return value_.value(); } 50 template <typename U> value_or(U && default_val)51 T value_or(U&& default_val) { 52 return value_.value_or(std::forward<U>(default_val)); 53 } 54 55 private: 56 absl::optional<T> value_; 57 }; 58 59 template <typename Derived, typename T> 60 std::ostream& operator<<(std::ostream& os, 61 ComplexOption<Derived, T> const& rhs) { 62 if (rhs.has_value()) { 63 return os << rhs.option_name() << "=" << rhs.value(); 64 } 65 return os << rhs.option_name() << "=<not set>"; 66 } 67 68 } // namespace internal 69 } // namespace STORAGE_CLIENT_NS 70 } // namespace storage 71 } // namespace cloud 72 } // namespace google 73 74 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_COMPLEX_OPTION_H 75