-- 506fa3e10b3d8399ad937c32ecea26d1ad4e62bb by Abseil Team <absl-team@google.com>: Disable ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE when GCC < 8.2.0 is used with libc++ PiperOrigin-RevId: 399707056 -- 656b7c7cee87f46a4bc7953618796f82da08e62c by Derek Mauro <dmauro@google.com>: Remove the MSVC flag implementation from flag.h to help clarify that methods on absl::Flag<T> are not part of the public API PiperOrigin-RevId: 399584678 -- a92a9bc156303bc663b84c4b704891ec8f67e333 by Abseil Team <absl-team@google.com>: Get rid of MemcpyIfAllowed while continuing to suppress erroneous warnings PiperOrigin-RevId: 399468864 -- 5f9a66895f707ba001fb51b88c0c6025f8c872a3 by Abseil Team <absl-team@google.com>: Use feature testing to check for availability of invoke_result. Feature testing should be available by C++20, which removes invoke_result. https://en.cppreference.com/w/cpp/feature_test PiperOrigin-RevId: 399447373 -- 946c0a502b4499dbfcabf1ab93ddde0048288fb4 by CJ Johnson <johnsoncj@google.com>: Add rvalue-reference qualifier to the Commit method on ConstructionTransaction PiperOrigin-RevId: 399442206 -- 726a4d036eff49aeb6fd0ca2b1775699b6844395 by Greg Falcon <gfalcon@google.com>: Internal change PiperOrigin-RevId: 399441870 -- 1df6d3f659b88dbac13c3d8e13db23bb3844ece2 by Abseil Team <absl-team@google.com>: Clang-format whitespace changes PiperOrigin-RevId: 399281271 -- 4a828cde95a07421d699ebac775b37810624214f by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 399234071 -- e520c72b34ba2f98668c889139001f8276243d31 by Greg Falcon <gfalcon@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 399233662 GitOrigin-RevId: 506fa3e10b3d8399ad937c32ecea26d1ad4e62bb Change-Id: I92b9176d2387c08eb167f9268efa78b55b8e09c2pull/1032/head
parent
7143e49e74
commit
4167eab063
54 changed files with 158 additions and 162 deletions
@ -0,0 +1,116 @@ |
||||
// |
||||
// Copyright 2021 The Abseil Authors. |
||||
// |
||||
// Licensed under the Apache License, Version 2.0 (the "License"); |
||||
// you may not use this file except in compliance with the License. |
||||
// You may obtain a copy of the License at |
||||
// |
||||
// https://www.apache.org/licenses/LICENSE-2.0 |
||||
// |
||||
// Unless required by applicable law or agreed to in writing, software |
||||
// distributed under the License is distributed on an "AS IS" BASIS, |
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
// See the License for the specific language governing permissions and |
||||
// limitations under the License. |
||||
|
||||
// Do not include this file directly. |
||||
// Include absl/flags/flag.h instead. |
||||
|
||||
// MSVC debug builds do not implement initialization with constexpr constructors |
||||
// correctly. To work around this we add a level of indirection, so that the |
||||
// class `absl::Flag` contains an `internal::Flag*` (instead of being an alias |
||||
// to that class) and dynamically allocates an instance when necessary. We also |
||||
// forward all calls to internal::Flag methods via trampoline methods. In this |
||||
// setup the `absl::Flag` class does not have constructor and virtual methods, |
||||
// all the data members are public and thus MSVC is able to initialize it at |
||||
// link time. To deal with multiple threads accessing the flag for the first |
||||
// time concurrently we use an atomic boolean indicating if flag object is |
||||
// initialized. We also employ the double-checked locking pattern where the |
||||
// second level of protection is a global Mutex, so if two threads attempt to |
||||
// construct the flag concurrently only one wins. |
||||
// |
||||
// This solution is based on a recomendation here: |
||||
// https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html?childToView=648454#comment-648454 |
||||
|
||||
namespace flags_internal { |
||||
absl::Mutex* GetGlobalConstructionGuard(); |
||||
} // namespace flags_internal |
||||
|
||||
// Public methods of `absl::Flag<T>` are NOT part of the Abseil Flags API. |
||||
// See https://abseil.io/docs/cpp/guides/flags |
||||
template <typename T> |
||||
class Flag { |
||||
public: |
||||
// No constructor and destructor to ensure this is an aggregate type. |
||||
// Visual Studio 2015 still requires the constructor for class to be |
||||
// constexpr initializable. |
||||
#if _MSC_VER <= 1900 |
||||
constexpr Flag(const char* name, const char* filename, |
||||
const flags_internal::HelpGenFunc help_gen, |
||||
const flags_internal::FlagDfltGenFunc default_value_gen) |
||||
: name_(name), |
||||
filename_(filename), |
||||
help_gen_(help_gen), |
||||
default_value_gen_(default_value_gen), |
||||
inited_(false), |
||||
impl_(nullptr) {} |
||||
#endif |
||||
|
||||
flags_internal::Flag<T>& GetImpl() const { |
||||
if (!inited_.load(std::memory_order_acquire)) { |
||||
absl::MutexLock l(flags_internal::GetGlobalConstructionGuard()); |
||||
|
||||
if (inited_.load(std::memory_order_acquire)) { |
||||
return *impl_; |
||||
} |
||||
|
||||
impl_ = new flags_internal::Flag<T>( |
||||
name_, filename_, |
||||
{flags_internal::FlagHelpMsg(help_gen_), |
||||
flags_internal::FlagHelpKind::kGenFunc}, |
||||
{flags_internal::FlagDefaultSrc(default_value_gen_), |
||||
flags_internal::FlagDefaultKind::kGenFunc}); |
||||
inited_.store(true, std::memory_order_release); |
||||
} |
||||
|
||||
return *impl_; |
||||
} |
||||
|
||||
// Public methods of `absl::Flag<T>` are NOT part of the Abseil Flags API. |
||||
// See https://abseil.io/docs/cpp/guides/flags |
||||
bool IsRetired() const { return GetImpl().IsRetired(); } |
||||
absl::string_view Name() const { return GetImpl().Name(); } |
||||
std::string Help() const { return GetImpl().Help(); } |
||||
bool IsModified() const { return GetImpl().IsModified(); } |
||||
bool IsSpecifiedOnCommandLine() const { |
||||
return GetImpl().IsSpecifiedOnCommandLine(); |
||||
} |
||||
std::string Filename() const { return GetImpl().Filename(); } |
||||
std::string DefaultValue() const { return GetImpl().DefaultValue(); } |
||||
std::string CurrentValue() const { return GetImpl().CurrentValue(); } |
||||
template <typename U> |
||||
inline bool IsOfType() const { |
||||
return GetImpl().template IsOfType<U>(); |
||||
} |
||||
T Get() const { |
||||
return flags_internal::FlagImplPeer::InvokeGet<T>(GetImpl()); |
||||
} |
||||
void Set(const T& v) { |
||||
flags_internal::FlagImplPeer::InvokeSet(GetImpl(), v); |
||||
} |
||||
void InvokeCallback() { GetImpl().InvokeCallback(); } |
||||
|
||||
const CommandLineFlag& Reflect() const { |
||||
return flags_internal::FlagImplPeer::InvokeReflect(GetImpl()); |
||||
} |
||||
|
||||
// The data members are logically private, but they need to be public for |
||||
// this to be an aggregate type. |
||||
const char* name_; |
||||
const char* filename_; |
||||
const flags_internal::HelpGenFunc help_gen_; |
||||
const flags_internal::FlagDfltGenFunc default_value_gen_; |
||||
|
||||
mutable std::atomic<bool> inited_; |
||||
mutable flags_internal::Flag<T>* impl_; |
||||
}; |
@ -1 +1 @@ |
||||
2021a |
||||
2021b |
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue