jitcraft/Handles.h
author David Anderson <dvander@alliedmods.net>
Sun Jul 08 01:54:08 2012 -0700 (2012-07-08)
changeset 60 581a9c793062
parent 59 b7d61ddb3c8d
child 83 79265b56316e
permissions -rw-r--r--
Initial import of some kind of API.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     7  * JITCraft is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * JITCraft. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #ifndef _include_jitcraft_rooting_h_
    20 #define _include_jitcraft_rooting_h_
    21 
    22 namespace ke {
    23 
    24 class Zone;
    25 class Object;
    26 
    27 template <typename T> class Local;
    28 template <typename T> class ScopedRoot;
    29 
    30 /*
    31  * Internal handles work differently from API handles. An API handle is a
    32  * root, whereas as an internal handle points to a rooted location. This
    33  * subtle difference makes handles easy for embedders, but somewhat
    34  * cumbersome internally.
    35  */
    36 template <typename T>
    37 class Handle
    38 {
    39     T * const *thingp_;
    40 
    41   public:
    42     Handle(const Handle &other) {
    43         thingp_ = other.address();
    44     }
    45     template <typename S> Handle(const Handle<S> &handle) {
    46         typeCheck<S>();
    47         thingp_ = reinterpret_cast<T * const *>(handle.address());
    48     }
    49     template <typename S> inline Handle(const Local<S> &local);
    50     template <typename S> inline Handle(const ScopedRoot<S> &root);
    51 
    52   public:
    53     T *operator ->() {
    54         return *thingp_;
    55     }
    56     T *operator *() {
    57         return *thingp_;
    58     }
    59     operator T *() { return *thingp_; }
    60     operator bool() const {
    61         return thingp_ && *thingp_;
    62     }
    63     T * const *address() const {
    64         return thingp_;
    65     }
    66 
    67   private:
    68     template <typename S>
    69     void typeCheck() {
    70 #ifdef DEBUG
    71         T *v1 = NULL;
    72         S *v2 = NULL;
    73         v1 = v2;
    74         (void)v1;
    75 #endif
    76     }
    77 };
    78 
    79 template <typename T>
    80 class Local
    81 {
    82     friend class Zone;
    83 
    84     Zone *zone_;
    85     T *thing_;
    86     Local<Object> *prev_;
    87 
    88     Local<Object> *prev() {
    89         return prev_;
    90     }
    91     Local<Object> *toRaw() {
    92         return reinterpret_cast<Local<Object>*>(this);
    93     }
    94 
    95   public:
    96     // These are implemented in Zone.h.
    97     inline explicit Local(Zone *zone, T *thing = NULL);
    98     inline ~Local();
    99 
   100     const Local &operator =(T *thing) {
   101         thing_ = thing;
   102         return *this;
   103     }
   104     T *operator ->() const {
   105         return operator *();
   106     }
   107     T *operator *() const {
   108         return thing_;
   109     }
   110     operator bool () const {
   111         return !!thing_;
   112     }
   113 
   114     Object **address() {
   115         return (Object **)&thing_;
   116     }
   117     Object * const *address() const {
   118         return (Object * const *)&thing_;
   119     }
   120     T **ref() {
   121         return &thing_;
   122     }
   123     operator T *() {
   124         return thing_;
   125     }
   126 
   127   private:
   128     // Disallow heap allocation.
   129     void *operator new(size_t size);
   130     void *operator new[](size_t size);
   131 
   132     // Disallow copy construction.
   133     Local(const Local<T> &other);
   134     Local &operator =(const Local &other);
   135 };
   136 
   137 // A ScopedRoot is a special kind of handle for storing references on the
   138 // heap in bulk.
   139 template <typename T>
   140 class ScopedRoot
   141 {
   142     T **thingp_;
   143 
   144   private:
   145     // This is implemented in Zone.h.
   146     inline T **make(T *other);
   147 
   148     void assign(T *other) {
   149         *thingp_ = other;
   150     }
   151 
   152   public:
   153     ScopedRoot();
   154 
   155     // This is implemented in Zone.h.
   156     inline ScopedRoot(T *thing);
   157 
   158     ScopedRoot &operator =(const ScopedRoot<T> &other) {
   159         assign(*other);
   160         return *this;
   161     }
   162     ScopedRoot &operator =(T *other) {
   163         assign(other);
   164         return *this;
   165     }
   166     T *operator ->() const {
   167         return operator *();
   168     }
   169     T *operator *() const {
   170         return *thingp_;
   171     }
   172     operator T *() const {
   173         return *thingp_;
   174     }
   175     operator bool () const {
   176         return !!*thingp_;
   177     }
   178     T **address() const {
   179         return thingp_;
   180     }
   181 };
   182 
   183 template <typename T> template <typename S> inline
   184 Handle<T>::Handle(const Local<S> &local)
   185 {
   186     typeCheck<S>();
   187     thingp_ = reinterpret_cast<T * const *>(local.address());
   188 }
   189 
   190 template <typename T> template <typename S> inline
   191 Handle<T>::Handle(const ScopedRoot<S> &root)
   192 {
   193     typeCheck<S>();
   194     thingp_ = reinterpret_cast<T * const *>(root.address());
   195 }
   196 
   197 }
   198 
   199 #endif // _include_jitcraft_rooting_h_