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