jitcraft/Handles.h
author David Anderson <dvander@alliedmods.net>
Tue Jul 03 00:21:37 2012 -0700 (2012-07-03)
changeset 29 c0e27b4f0672
parent 28 a9665857cfd5
child 34 9aafaf3797e6
permissions -rw-r--r--
Added RootScopes for AST roots.
     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 #include "Objects.h"
    23 
    24 namespace jc {
    25 
    26 class Zone;
    27 
    28 template <typename T> class Local;
    29 template <typename T> class ScopedRoot;
    30 
    31 template <typename T>
    32 class Handle
    33 {
    34     T * const *thingp_;
    35 
    36   public:
    37     template <typename S> Handle(const Handle<S> &handle) {
    38         typeCheck<S>();
    39         thingp_ = reinterpret_cast<T * const *>(handle.address());
    40     }
    41     template <typename S> inline Handle(const Local<S> &local);
    42     template <typename S> inline Handle(const ScopedRoot<S> &root);
    43 
    44   public:
    45     T *operator ->() {
    46         return *thingp_;
    47     }
    48     T *operator *() {
    49         return *thingp_;
    50     }
    51     operator T *() { return *thingp_; }
    52     operator bool() const {
    53         return thingp_ && *thingp_;
    54     }
    55     T * const *address() const {
    56         return thingp_;
    57     }
    58 
    59   private:
    60     template <typename S>
    61     void typeCheck() {
    62 #ifdef DEBUG
    63         T *v1 = NULL;
    64         S *v2 = NULL;
    65         v1 = v2;
    66         (void)v1;
    67 #endif
    68     }
    69 };
    70 
    71 template <typename T>
    72 class Local
    73 {
    74     friend class Zone;
    75 
    76     Zone *zone_;
    77     T *thing_;
    78     Local<Object> *prev_;
    79 
    80     Local<Object> *prev() {
    81         return prev_;
    82     }
    83     Local<Object> *toRaw() {
    84         return reinterpret_cast<Local<Object>*>(this);
    85     }
    86 
    87   public:
    88     // These are implemented in Zone.h.
    89     inline explicit Local(Zone *zone, T *thing = NULL);
    90     inline ~Local();
    91 
    92     const Local &operator =(T *thing) {
    93         thing_ = thing;
    94         return *this;
    95     }
    96     T *operator ->() const {
    97         return operator *();
    98     }
    99     T *operator *() const {
   100         return thing_;
   101     }
   102     operator bool () const {
   103         return !!thing_;
   104     }
   105 
   106     Object **address() {
   107         return (Object **)&thing_;
   108     }
   109     Object * const *address() const {
   110         return (Object * const *)&thing_;
   111     }
   112     operator T *() {
   113         return thing_;
   114     }
   115 
   116   private:
   117     // Disallow heap allocation.
   118     void *operator new(size_t size);
   119     void *operator new[](size_t size);
   120 
   121     // Disallow copy construction.
   122     Local(const Local<T> &other);
   123     Local &operator =(const Local &other);
   124 };
   125 
   126 // A ScopedRoot is a special kind of handle for storing references on the
   127 // heap in bulk.
   128 template <typename T>
   129 class ScopedRoot
   130 {
   131     T **thingp_;
   132 
   133   private:
   134     // This is implemented in Zone.h.
   135     inline T **make(T *other);
   136 
   137     void assign(T *other) {
   138         if (!thingp_)
   139             thingp_ = make(other);
   140         else
   141             *thingp_ = other;
   142     }
   143 
   144   public:
   145     ScopedRoot()
   146     { }
   147 
   148     // This is implemented in Zone.h.
   149     inline ScopedRoot(T *thing);
   150 
   151     ScopedRoot &operator =(const ScopedRoot<T> &other) {
   152         assign(*other);
   153         return *this;
   154     }
   155     ScopedRoot &operator =(T *other) {
   156         assign(other);
   157         return *this;
   158     }
   159     T *operator ->() const {
   160         return operator *();
   161     }
   162     T *operator *() const {
   163         return *thingp_;
   164     }
   165     operator T *() const {
   166         return thingp_ ? *thingp_ : NULL;
   167     }
   168     operator bool () const {
   169         return thingp_ && *thingp_;
   170     }
   171 };
   172 
   173 template <typename T> template <typename S> inline
   174 Handle<T>::Handle(const Local<S> &local)
   175 {
   176     typeCheck<S>();
   177     thingp_ = reinterpret_cast<T * const*>(local.address());
   178 }
   179 
   180 }
   181 
   182 #endif // _include_jitcraft_rooting_h_