| // flag.h | |
| template <typename T> | |
| class Flag { | |
| public: | |
| T Get() const { | |
| // See implementation notes in CommandLineFlag::Get(). | |
| union U { | |
| T value; | |
| U() {} | |
| ~U() { value.~T(); } | |
| }; | |
| U u; | |
| // Operations are good to check that the flag was declared with the same type. | |
| // IF THIS COMES FROM SHARED library. | |
| impl_.Read(&u.value, &flags_internal::FlagOps<T>); | |
| return std::move(u.value); | |
| } | |
| } | |
| // flag.cc | |
| void FlagImpl::Read(void* dst, const flags_internal::FlagOpFn dst_op) const { | |
| absl::ReaderMutexLock l(DataGuard()); | |
| // `dst_op` is the unmarshaling operation corresponding to the declaration | |
| // visibile at the call site. `op` is the Flag's defined unmarshalling | |
| // operation. They must match for this operation to be well-defined. | |
| // THIS IS NOT TRUE ANYMORE AS POINTERS FROM SHARED LIBRARIES ARE | |
| // DIFFERENT FROM STATIC INITIALIZATION. | |
| if (ABSL_PREDICT_FALSE(dst_op != op_)) { | |
| ABSL_INTERNAL_LOG( | |
| ERROR, | |
| absl::StrCat("Flag '", Name(), | |
| "' is defined as one type and declared as another")); | |
| } | |
| CopyConstruct(op_, cur_, dst); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment