Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iomanip>
- #include <iostream>
- #include <memory>
- #include <mutex>
- #include <optional>
- #include <vector>
- // Took here cause lazy:
- // https://github.com/adobe/chromium/blob/master/third_party/tcmalloc/vendor/src/base/thread_annotations.h
- #if defined(__GNUC__) && \
- (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) && \
- defined(__SUPPORT_TS_ANNOTATION__) && (!defined(SWIG))
- #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
- #else
- #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
- #endif
- #define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
- #define GUARDED_VAR THREAD_ANNOTATION_ATTRIBUTE__(guarded)
- // Note: current implementation tightly couples contained object wrapper and
- // container because I was lazy. You can clean this up if you'd like.
- struct ContainedObject {
- int value = 0;
- };
- class Container {
- public:
- class ContainedObjectWrapper {
- public:
- ContainedObjectWrapper(std::unique_ptr<ContainedObject> contained_object,
- Container *parent_container)
- : contained_object_(std::move(contained_object)),
- parent_container_(parent_container) {}
- // Add error checking etc. if you need...
- ContainedObject &GetWrappedValue() { return *contained_object_; }
- ~ContainedObjectWrapper() {
- parent_container_->AddValue(std::move(contained_object_));
- // Unnecessary, but explicit.
- contained_object_ = nullptr;
- }
- private:
- std::unique_ptr<ContainedObject> contained_object_;
- Container *parent_container_;
- };
- // If you make a separate "GetValue" and "HasValue" you have potential "time
- // of check vs. time of use" kinds of bugs.
- std::unique_ptr<ContainedObjectWrapper> GetValueWrapper() {
- std::lock_guard<std::mutex> lock(mu_);
- if (values_.empty()) {
- return {};
- } else {
- auto retval = std::make_unique<ContainedObjectWrapper>(
- std::move(values_.back()), this);
- values_.pop_back();
- return retval;
- }
- }
- void AddValue(std::unique_ptr<ContainedObject> contained_object) {
- std::lock_guard<std::mutex> lock(mu_);
- values_.push_back(std::move(contained_object));
- }
- private:
- std::vector<std::unique_ptr<ContainedObject>> values_ GUARDED_BY(mu_);
- std::mutex mu_;
- };
- int main() {
- Container container;
- auto object = std::make_unique<ContainedObject>();
- object->value = 31337;
- container.AddValue(std::move(object));
- std::cout << std::boolalpha;
- {
- auto value_wrapper = container.GetValueWrapper();
- std::cout << (value_wrapper == nullptr) << '\n';
- auto &value = value_wrapper->GetWrappedValue();
- std::cout << value.value << '\n';
- }
- {
- auto value_wrapper = container.GetValueWrapper();
- std::cout << (value_wrapper == nullptr) << '\n';
- auto &value = value_wrapper->GetWrappedValue();
- std::cout << value.value << '\n';
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement