this repo has no description
at trunk 83 lines 2.4 kB view raw
1/* Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) */ 2#pragma once 3 4#include "handles-decl.h" 5#include "objects.h" 6#include "thread.h" 7 8namespace py { 9 10class WARN_UNUSED HandleScope { 11 public: 12 explicit HandleScope(Thread* thread) : thread_(thread) {} 13 14 Thread* thread() const { return thread_; } 15 16 private: 17 Thread* const thread_; 18 19 DISALLOW_COPY_AND_ASSIGN(HandleScope); 20}; 21 22template <typename T> 23class WARN_UNUSED Handle : public T { 24 public: 25 Handle(HandleScope* scope, RawObject obj) 26 : T(obj.rawCast<T>()), 27 thread_(scope->thread()), 28 next_(thread_->handles()->push(pointer())) { 29 DCHECK(isValidType(), "Invalid Handle construction"); 30 } 31 32 // Don't allow constructing a Handle directly from another Handle; require 33 // dereferencing the source. 34 template <typename S> 35 Handle(HandleScope*, const Handle<S>&) = delete; 36 37 ~Handle() { 38 DCHECK(thread_->handles()->head() == pointer(), "unexpected this"); 39 thread_->handles()->pop(next_); 40 } 41 42 Handle<RawObject>* nextHandle() const { return next_; } 43 44 T operator*() const { return *static_cast<const T*>(this); } 45 46 // Note that Handle<T>::operator= takes a raw pointer, not a handle, so 47 // to assign handles, one writes: `lhandle = *rhandle;`. (This is to avoid 48 // confusion about which HandleScope tracks lhandle after the assignment.) 49 template <typename S> 50 Handle& operator=(S other) { 51 static_assert(std::is_base_of<S, T>::value || std::is_base_of<T, S>::value, 52 "Only up- and down-casts are permitted."); 53 *static_cast<T*>(this) = other.template rawCast<T>(); 54 DCHECK(isValidType(), "Invalid Handle assignment"); 55 return *this; 56 } 57 58 // Let Handle<T> pretend to be a subtype of Handle<S> when T is a subtype of 59 // S. 60 template <typename S> 61 operator const Handle<S> &() const { 62 static_assert(std::is_base_of<S, T>::value, "Only up-casts are permitted"); 63 return *reinterpret_cast<const Handle<S>*>(this); 64 } 65 66 static_assert(std::is_base_of<RawObject, T>::value, 67 "You can only get a handle to a py::RawObject."); 68 69 DISALLOW_IMPLICIT_CONSTRUCTORS(Handle); 70 DISALLOW_HEAP_ALLOCATION(); 71 72 private: 73 bool isValidType() const; 74 75 Handle<RawObject>* pointer() { 76 return reinterpret_cast<Handle<RawObject>*>(this); 77 } 78 79 Thread* const thread_; 80 Handle<RawObject>* const next_; 81}; 82 83} // namespace py