-- 9e8b4a286d70df9487bff080816bd07ae38af5f8 by Evan Brown <ezb@google.com>: Add btree_node::transfer_n/transfer_n_backward and replace usage of uninitialized_move_n and value_destroy_n. PiperOrigin-RevId: 314600027 -- 6c452aa1ee7e46ab941ba7d1fa636da8ea3d7370 by Laramie Leavitt <lar@google.com>: Remove the MockingBitGenBase base class in favor of type-erasure in BitGenRef. In Abseil random, mocking was split across two different classes, MockingBitGenBase and MockingBitGen. This split existed because Google Mock is a test-only library that we don't link into production, so MockingBitGenBase provided a low-overhead scaffold used to lookup mocks when in test code, but which is unused in production code. That has been replaced by type-erasure which looks for a method named CallImpl with the correct signature. Weaken the coupling between MockingBitGen, DistributionCaller, and MockOverloadSet. Rename CallImpl to InvokeMock() Previously, the implementation of DistributionCaller was also split across different files using explicit instantiation of the DistributionCaller struct and some details in the Mocking classes. Now Distribution caller uses the presence of the InvokeMock() method to choose whether to use the mockable call path or the default call path. PiperOrigin-RevId: 314584095 -- 07853c47dc98698d67d65a3b9b662a65ab9def0a by Abseil Team <absl-team@google.com>: Add PC / backtrace / symbolization support for Apple platforms. Full backtrace support requires iOS 9+ PiperOrigin-RevId: 314415072 -- 43889f17a132b31f6558c6482721cbbc776128fd by Gennadiy Rozental <rogeeff@google.com>: Consolidate all reflection interface in the new module 'reflection' and expose interface to locate reflection handle by name. PiperOrigin-RevId: 314390358 GitOrigin-RevId: 9e8b4a286d70df9487bff080816bd07ae38af5f8 Change-Id: I8e0910437740cf9ea9da5000adddfcef127e1158pull/705/head
parent
da3a87690c
commit
1d31b5c365
34 changed files with 783 additions and 885 deletions
@ -0,0 +1,101 @@ |
||||
// Copyright 2020 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. |
||||
|
||||
#include <cxxabi.h> |
||||
#include <execinfo.h> |
||||
|
||||
#include <algorithm> |
||||
#include <cstring> |
||||
|
||||
#include "absl/base/internal/raw_logging.h" |
||||
#include "absl/debugging/internal/demangle.h" |
||||
#include "absl/strings/numbers.h" |
||||
#include "absl/strings/str_cat.h" |
||||
#include "absl/strings/string_view.h" |
||||
|
||||
namespace absl { |
||||
ABSL_NAMESPACE_BEGIN |
||||
|
||||
void InitializeSymbolizer(const char*) {} |
||||
|
||||
namespace debugging_internal { |
||||
namespace { |
||||
|
||||
static std::string GetSymbolString(absl::string_view backtrace_line) { |
||||
// Example Backtrace lines: |
||||
// 0 libimaging_shared.dylib 0x018c152a |
||||
// _ZNSt11_Deque_baseIN3nik7mediadb4PageESaIS2_EE17_M_initialize_mapEm + 3478 |
||||
// |
||||
// or |
||||
// 0 libimaging_shared.dylib 0x0000000001895c39 |
||||
// _ZN3nik4util19register_shared_ptrINS_3gpu7TextureEEEvPKvS5_ + 39 |
||||
// |
||||
// or |
||||
// 0 mysterious_app 0x0124000120120009 main + 17 |
||||
auto address_pos = backtrace_line.find(" 0x"); |
||||
if (address_pos == absl::string_view::npos) return std::string(); |
||||
absl::string_view symbol_view = backtrace_line.substr(address_pos + 1); |
||||
|
||||
auto space_pos = symbol_view.find(" "); |
||||
if (space_pos == absl::string_view::npos) return std::string(); |
||||
symbol_view = symbol_view.substr(space_pos + 1); // to mangled symbol |
||||
|
||||
auto plus_pos = symbol_view.find(" + "); |
||||
if (plus_pos == absl::string_view::npos) return std::string(); |
||||
symbol_view = symbol_view.substr(0, plus_pos); // strip remainng |
||||
|
||||
return std::string(symbol_view); |
||||
} |
||||
|
||||
} // namespace |
||||
} // namespace debugging_internal |
||||
|
||||
bool Symbolize(const void* pc, char* out, int out_size) { |
||||
if (out_size <= 0 || pc == nullptr) { |
||||
out = nullptr; |
||||
return false; |
||||
} |
||||
|
||||
// This allocates a char* array. |
||||
char** frame_strings = backtrace_symbols(const_cast<void**>(&pc), 1); |
||||
|
||||
if (frame_strings == nullptr) return false; |
||||
|
||||
std::string symbol = debugging_internal::GetSymbolString(frame_strings[0]); |
||||
free(frame_strings); |
||||
|
||||
char tmp_buf[1024]; |
||||
if (debugging_internal::Demangle(symbol.c_str(), tmp_buf, sizeof(tmp_buf))) { |
||||
int len = strlen(tmp_buf); |
||||
if (len + 1 <= out_size) { // +1 for '\0' |
||||
assert(len < sizeof(tmp_buf)); |
||||
memmove(out, tmp_buf, len + 1); |
||||
} |
||||
} else { |
||||
strncpy(out, symbol.c_str(), out_size); |
||||
} |
||||
|
||||
if (out[out_size - 1] != '\0') { |
||||
// strncpy() does not '\0' terminate when it truncates. |
||||
static constexpr char kEllipsis[] = "..."; |
||||
int ellipsis_size = std::min<int>(sizeof(kEllipsis) - 1, out_size - 1); |
||||
memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); |
||||
out[out_size - 1] = '\0'; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
ABSL_NAMESPACE_END |
||||
} // namespace absl |
@ -1,86 +0,0 @@ |
||||
//
|
||||
// Copyright 2019 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.
|
||||
|
||||
#include "absl/flags/internal/type_erased.h" |
||||
|
||||
#include <assert.h> |
||||
|
||||
#include <string> |
||||
|
||||
#include "absl/base/config.h" |
||||
#include "absl/base/internal/raw_logging.h" |
||||
#include "absl/flags/commandlineflag.h" |
||||
#include "absl/flags/internal/private_handle_accessor.h" |
||||
#include "absl/flags/internal/registry.h" |
||||
#include "absl/flags/usage_config.h" |
||||
#include "absl/strings/string_view.h" |
||||
|
||||
namespace absl { |
||||
ABSL_NAMESPACE_BEGIN |
||||
namespace flags_internal { |
||||
|
||||
bool GetCommandLineOption(absl::string_view name, std::string* value) { |
||||
if (name.empty()) return false; |
||||
assert(value); |
||||
|
||||
CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); |
||||
if (flag == nullptr || flag->IsRetired()) { |
||||
return false; |
||||
} |
||||
|
||||
*value = flag->CurrentValue(); |
||||
return true; |
||||
} |
||||
|
||||
bool SetCommandLineOption(absl::string_view name, absl::string_view value) { |
||||
return SetCommandLineOptionWithMode(name, value, |
||||
flags_internal::SET_FLAGS_VALUE); |
||||
} |
||||
|
||||
bool SetCommandLineOptionWithMode(absl::string_view name, |
||||
absl::string_view value, |
||||
FlagSettingMode set_mode) { |
||||
CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); |
||||
|
||||
if (!flag || flag->IsRetired()) return false; |
||||
|
||||
std::string error; |
||||
if (!flags_internal::PrivateHandleAccessor::ParseFrom( |
||||
*flag, value, set_mode, kProgrammaticChange, error)) { |
||||
// Errors here are all of the form: the provided name was a recognized
|
||||
// flag, but the value was invalid (bad type, or validation failed).
|
||||
flags_internal::ReportUsageError(error, false); |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
bool IsValidFlagValue(absl::string_view name, absl::string_view value) { |
||||
CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); |
||||
|
||||
return flag != nullptr && |
||||
(flag->IsRetired() || |
||||
flags_internal::PrivateHandleAccessor::ValidateInputValue(*flag, |
||||
value)); |
||||
} |
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
} // namespace flags_internal
|
||||
ABSL_NAMESPACE_END |
||||
} // namespace absl
|
@ -1,80 +0,0 @@ |
||||
//
|
||||
// Copyright 2019 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.
|
||||
|
||||
#ifndef ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_ |
||||
#define ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_ |
||||
|
||||
#include <string> |
||||
|
||||
#include "absl/base/config.h" |
||||
#include "absl/flags/commandlineflag.h" |
||||
#include "absl/flags/internal/commandlineflag.h" |
||||
#include "absl/flags/internal/registry.h" |
||||
#include "absl/strings/string_view.h" |
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Registry interfaces operating on type erased handles.
|
||||
|
||||
namespace absl { |
||||
ABSL_NAMESPACE_BEGIN |
||||
namespace flags_internal { |
||||
|
||||
// If a flag named "name" exists, store its current value in *OUTPUT
|
||||
// and return true. Else return false without changing *OUTPUT.
|
||||
// Thread-safe.
|
||||
bool GetCommandLineOption(absl::string_view name, std::string* value); |
||||
|
||||
// Set the value of the flag named "name" to value. If successful,
|
||||
// returns true. If not successful (e.g., the flag was not found or
|
||||
// the value is not a valid value), returns false.
|
||||
// Thread-safe.
|
||||
bool SetCommandLineOption(absl::string_view name, absl::string_view value); |
||||
|
||||
bool SetCommandLineOptionWithMode(absl::string_view name, |
||||
absl::string_view value, |
||||
FlagSettingMode set_mode); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Returns true iff all of the following conditions are true:
|
||||
// (a) "name" names a registered flag
|
||||
// (b) "value" can be parsed succesfully according to the type of the flag
|
||||
// (c) parsed value passes any validator associated with the flag
|
||||
bool IsValidFlagValue(absl::string_view name, absl::string_view value); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// If a flag with specified "name" exists and has type T, store
|
||||
// its current value in *dst and return true. Else return false
|
||||
// without touching *dst. T must obey all of the requirements for
|
||||
// types passed to DEFINE_FLAG.
|
||||
template <typename T> |
||||
inline bool GetByName(absl::string_view name, T* dst) { |
||||
CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); |
||||
if (!flag) return false; |
||||
|
||||
if (auto val = flag->TryGet<T>()) { |
||||
*dst = *val; |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
} // namespace flags_internal
|
||||
ABSL_NAMESPACE_END |
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_
|
@ -1,156 +0,0 @@ |
||||
//
|
||||
// Copyright 2019 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.
|
||||
|
||||
#include "absl/flags/internal/type_erased.h" |
||||
|
||||
#include <memory> |
||||
#include <string> |
||||
|
||||
#include "gtest/gtest.h" |
||||
#include "absl/flags/flag.h" |
||||
#include "absl/flags/internal/commandlineflag.h" |
||||
#include "absl/flags/internal/registry.h" |
||||
#include "absl/memory/memory.h" |
||||
|
||||
ABSL_FLAG(int, int_flag, 1, "int_flag help"); |
||||
ABSL_FLAG(std::string, string_flag, "dflt", "string_flag help"); |
||||
ABSL_RETIRED_FLAG(bool, bool_retired_flag, false, "bool_retired_flag help"); |
||||
|
||||
namespace { |
||||
|
||||
namespace flags = absl::flags_internal; |
||||
|
||||
class TypeErasedTest : public testing::Test { |
||||
protected: |
||||
void SetUp() override { flag_saver_ = absl::make_unique<flags::FlagSaver>(); } |
||||
void TearDown() override { flag_saver_.reset(); } |
||||
|
||||
private: |
||||
std::unique_ptr<flags::FlagSaver> flag_saver_; |
||||
}; |
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
TEST_F(TypeErasedTest, TestGetCommandLineOption) { |
||||
std::string value; |
||||
EXPECT_TRUE(flags::GetCommandLineOption("int_flag", &value)); |
||||
EXPECT_EQ(value, "1"); |
||||
|
||||
EXPECT_TRUE(flags::GetCommandLineOption("string_flag", &value)); |
||||
EXPECT_EQ(value, "dflt"); |
||||
|
||||
EXPECT_FALSE(flags::GetCommandLineOption("bool_retired_flag", &value)); |
||||
|
||||
EXPECT_FALSE(flags::GetCommandLineOption("unknown_flag", &value)); |
||||
} |
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
TEST_F(TypeErasedTest, TestSetCommandLineOption) { |
||||
EXPECT_TRUE(flags::SetCommandLineOption("int_flag", "101")); |
||||
EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101); |
||||
|
||||
EXPECT_TRUE(flags::SetCommandLineOption("string_flag", "asdfgh")); |
||||
EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh"); |
||||
|
||||
EXPECT_FALSE(flags::SetCommandLineOption("bool_retired_flag", "true")); |
||||
|
||||
EXPECT_FALSE(flags::SetCommandLineOption("unknown_flag", "true")); |
||||
} |
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAGS_VALUE) { |
||||
EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101", |
||||
flags::SET_FLAGS_VALUE)); |
||||
EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101); |
||||
|
||||
EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh", |
||||
flags::SET_FLAGS_VALUE)); |
||||
EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh"); |
||||
|
||||
EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true", |
||||
flags::SET_FLAGS_VALUE)); |
||||
|
||||
EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true", |
||||
flags::SET_FLAGS_VALUE)); |
||||
} |
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAG_IF_DEFAULT) { |
||||
EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101", |
||||
flags::SET_FLAG_IF_DEFAULT)); |
||||
EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101); |
||||
|
||||
// This semantic is broken. We return true instead of false. Value is not
|
||||
// updated.
|
||||
EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "202", |
||||
flags::SET_FLAG_IF_DEFAULT)); |
||||
EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101); |
||||
|
||||
EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh", |
||||
flags::SET_FLAG_IF_DEFAULT)); |
||||
EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh"); |
||||
|
||||
EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true", |
||||
flags::SET_FLAG_IF_DEFAULT)); |
||||
|
||||
EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true", |
||||
flags::SET_FLAG_IF_DEFAULT)); |
||||
} |
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAGS_DEFAULT) { |
||||
EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101", |
||||
flags::SET_FLAGS_DEFAULT)); |
||||
|
||||
// Set it again to ensure that resetting logic is covered.
|
||||
EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "102", |
||||
flags::SET_FLAGS_DEFAULT)); |
||||
|
||||
EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "103", |
||||
flags::SET_FLAGS_DEFAULT)); |
||||
|
||||
EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh", |
||||
flags::SET_FLAGS_DEFAULT)); |
||||
EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh"); |
||||
|
||||
EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true", |
||||
flags::SET_FLAGS_DEFAULT)); |
||||
|
||||
EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true", |
||||
flags::SET_FLAGS_DEFAULT)); |
||||
|
||||
// This should be successfull, since flag is still is not set
|
||||
EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "202", |
||||
flags::SET_FLAG_IF_DEFAULT)); |
||||
EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 202); |
||||
} |
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
TEST_F(TypeErasedTest, TestIsValidFlagValue) { |
||||
EXPECT_TRUE(flags::IsValidFlagValue("int_flag", "57")); |
||||
EXPECT_TRUE(flags::IsValidFlagValue("int_flag", "-101")); |
||||
EXPECT_FALSE(flags::IsValidFlagValue("int_flag", "1.1")); |
||||
|
||||
EXPECT_TRUE(flags::IsValidFlagValue("string_flag", "#%^#%^$%DGHDG$W%adsf")); |
||||
|
||||
EXPECT_TRUE(flags::IsValidFlagValue("bool_retired_flag", "true")); |
||||
} |
||||
|
||||
} // namespace
|
@ -0,0 +1,47 @@ |
||||
//
|
||||
// Copyright 2020 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.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: reflection.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This file defines the routines to access and operate on an Abseil Flag's
|
||||
// reflection handle.
|
||||
|
||||
#ifndef ABSL_FLAGS_REFLECTION_H_ |
||||
#define ABSL_FLAGS_REFLECTION_H_ |
||||
|
||||
#include <string> |
||||
|
||||
#include "absl/base/config.h" |
||||
#include "absl/flags/commandlineflag.h" |
||||
#include "absl/flags/internal/commandlineflag.h" |
||||
|
||||
namespace absl { |
||||
ABSL_NAMESPACE_BEGIN |
||||
|
||||
// FindCommandLineFlag()
|
||||
//
|
||||
// Returns the reflection handle of an Abseil flag of the specified name, or
|
||||
// `nullptr` if not found. This function will emit a warning if the name of a
|
||||
// 'retired' flag is specified.
|
||||
CommandLineFlag* FindCommandLineFlag(absl::string_view name); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ABSL_NAMESPACE_END |
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_FLAGS_REFLECTION_H_
|
@ -0,0 +1,60 @@ |
||||
//
|
||||
// Copyright 2019 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.
|
||||
|
||||
#include "absl/flags/reflection.h" |
||||
|
||||
#include <memory> |
||||
#include <string> |
||||
|
||||
#include "gtest/gtest.h" |
||||
#include "absl/flags/flag.h" |
||||
#include "absl/flags/internal/commandlineflag.h" |
||||
#include "absl/flags/marshalling.h" |
||||
#include "absl/memory/memory.h" |
||||
|
||||
ABSL_FLAG(int, int_flag, 1, "int_flag help"); |
||||
ABSL_FLAG(std::string, string_flag, "dflt", "string_flag help"); |
||||
ABSL_RETIRED_FLAG(bool, bool_retired_flag, false, "bool_retired_flag help"); |
||||
|
||||
namespace { |
||||
|
||||
namespace flags = absl::flags_internal; |
||||
|
||||
class ReflectionTest : public testing::Test { |
||||
protected: |
||||
void SetUp() override { flag_saver_ = absl::make_unique<flags::FlagSaver>(); } |
||||
void TearDown() override { flag_saver_.reset(); } |
||||
|
||||
private: |
||||
std::unique_ptr<flags::FlagSaver> flag_saver_; |
||||
}; |
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
TEST_F(ReflectionTest, TestFindCommandLineFlag) { |
||||
auto* handle = absl::FindCommandLineFlag("some_flag"); |
||||
EXPECT_EQ(handle, nullptr); |
||||
|
||||
handle = absl::FindCommandLineFlag("int_flag"); |
||||
EXPECT_NE(handle, nullptr); |
||||
|
||||
handle = absl::FindCommandLineFlag("string_flag"); |
||||
EXPECT_NE(handle, nullptr); |
||||
|
||||
handle = absl::FindCommandLineFlag("bool_retired_flag"); |
||||
EXPECT_NE(handle, nullptr); |
||||
} |
||||
|
||||
} // namespace
|
@ -1,85 +0,0 @@ |
||||
//
|
||||
// Copyright 2018 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.
|
||||
//
|
||||
#ifndef ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ |
||||
#define ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ |
||||
|
||||
#include <string> |
||||
#include <typeinfo> |
||||
|
||||
#include "absl/random/random.h" |
||||
#include "absl/strings/str_cat.h" |
||||
|
||||
namespace absl { |
||||
ABSL_NAMESPACE_BEGIN |
||||
namespace random_internal { |
||||
|
||||
class MockingBitGenBase { |
||||
template <typename> |
||||
friend struct DistributionCaller; |
||||
using generator_type = absl::BitGen; |
||||
|
||||
public: |
||||
// URBG interface
|
||||
using result_type = generator_type::result_type; |
||||
static constexpr result_type(min)() { return (generator_type::min)(); } |
||||
static constexpr result_type(max)() { return (generator_type::max)(); } |
||||
result_type operator()() { return gen_(); } |
||||
|
||||
virtual ~MockingBitGenBase() = default; |
||||
|
||||
protected: |
||||
// CallImpl is the type-erased virtual dispatch.
|
||||
// The type of dist is always distribution<T>,
|
||||
// The type of result is always distribution<T>::result_type.
|
||||
virtual bool CallImpl(const std::type_info& distr_type, void* dist_args, |
||||
void* result) = 0; |
||||
|
||||
template <typename DistrT, typename ArgTupleT> |
||||
static const std::type_info& GetTypeId() { |
||||
return typeid(std::pair<absl::decay_t<DistrT>, absl::decay_t<ArgTupleT>>); |
||||
} |
||||
|
||||
// Call the generating distribution function.
|
||||
// Invoked by DistributionCaller<>::Call<DistT>.
|
||||
// DistT is the distribution type.
|
||||
template <typename DistrT, typename... Args> |
||||
typename DistrT::result_type Call(Args&&... args) { |
||||
using distr_result_type = typename DistrT::result_type; |
||||
using ArgTupleT = std::tuple<absl::decay_t<Args>...>; |
||||
|
||||
ArgTupleT arg_tuple(std::forward<Args>(args)...); |
||||
auto dist = absl::make_from_tuple<DistrT>(arg_tuple); |
||||
|
||||
distr_result_type result{}; |
||||
bool found_match = |
||||
CallImpl(GetTypeId<DistrT, ArgTupleT>(), &arg_tuple, &result); |
||||
|
||||
if (!found_match) { |
||||
result = dist(gen_); |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
private: |
||||
generator_type gen_; |
||||
}; // namespace random_internal
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END |
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_
|
Loading…
Reference in new issue