BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Object.h
Go to the documentation of this file.
00001 // Copyright (c) 2000  Utrecht University (The Netherlands),
00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
00005 // and Tel-Aviv University (Israel).  All rights reserved.
00006 //
00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public License as
00009 // published by the Free Software Foundation; version 2.1 of the License.
00010 // See the file LICENSE.LGPL distributed with CGAL.
00011 //
00012 // Licensees holding a valid commercial license may use this file in
00013 // accordance with the commercial license agreement provided with the software.
00014 //
00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 //
00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/STL_Extension/include/CGAL/Object.h $
00019 // $Id: Object.h 45448 2008-09-09 16:03:25Z spion $
00020 // 
00021 //
00022 // Author(s)     : Stefan Schirra
00023 //                 Andreas Fabri
00024 //                 Geert-Jan Giezeman
00025 //                 Michael Seel
00026 //                 Sylvain Pion
00027 
00028 #ifndef CGAL_OBJECT_H
00029 #define CGAL_OBJECT_H
00030 
00031 #include <CGAL/basic.h>
00032 #include <CGAL/Handle_for_virtual.h>
00033 
00034 #include <typeinfo>
00035 
00036 CGAL_BEGIN_NAMESPACE
00037 
00038 template <class T>
00039 class Wrapper : public Ref_counted_virtual
00040 {
00041     Wrapper(const Wrapper&); // deleted to make sure we don't make useless copies
00042   public:
00043 
00044     Wrapper(const T& object) : _object(object) {}
00045 
00046 #ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE
00047     Wrapper(T && object) : _object(std::move(object)) {}
00048 #endif
00049 
00050     ~Wrapper() {}
00051 
00052     const T& get() const { return _object; }
00053 
00054     virtual const std::type_info & type() const
00055     {
00056         return typeid(T);
00057     }
00058 
00059     virtual const void * object_ptr() const
00060     {
00061         return & _object;
00062     }
00063 
00064   private:
00065     T         _object;
00066 };
00067 
00068 class Object
00069   : public Handle_for_virtual<Ref_counted_virtual>
00070 {
00071     struct Empty {};
00072     typedef Handle_for_virtual<Ref_counted_virtual> base;
00073 
00074   public:
00075 
00076     struct private_tag{};
00077 
00078     Object()
00079     {
00080         typedef Wrapper<Empty>  Wrap;
00081         ptr = new Wrap(Empty());
00082     }
00083 
00084 #ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE
00085     template <class T>
00086     Object(T && t, private_tag)
00087     {
00088         typedef Wrapper< typename std::remove_cv< typename std::remove_reference<T>::type >::type >  Wrap;
00089         ptr = new Wrap(std::forward<T>(t));
00090     }
00091 #else
00092     template <class T>
00093     Object(const T&t, private_tag)
00094     {
00095         typedef Wrapper<T>  Wrap;
00096         ptr = new Wrap(t);
00097     }
00098 #endif
00099 
00100     template <class T>
00101     bool assign(T &t) const
00102     {
00103 #ifdef _MSC_VER
00104       try {
00105 #endif
00106         const Wrapper<T> *wp = dynamic_cast<const Wrapper<T> *>(Ptr());
00107         if (wp == NULL)
00108             return false;
00109         t = wp->get();
00110 #ifdef _MSC_VER
00111       }
00112       catch (...) {
00113           CGAL_error_msg("Your compiler must support Run-Time Type Information (RTTI)");
00114       }
00115 #endif
00116       return true;
00117     }
00118 
00119     bool
00120     empty() const
00121     {
00122         Empty E;
00123         return assign(E);
00124     }
00125 
00126     // is_empty() is kept for backward compatibility.
00127     // empty() was introduced for consistency with e.g. std::vector::empty().
00128     bool
00129     is_empty() const
00130     {
00131         return empty();
00132     }
00133 
00134     const std::type_info & type() const
00135     {
00136         return empty() ? typeid(void) : Ptr()->type();
00137     }
00138 
00139 #ifndef CGAL_NO_DEPRECATED_CODE
00140     // The comparisons with NULL are only there for Nef...
00141     bool operator==(Nullptr_t CGAL_assertion_code(n)) const
00142     { CGAL_assertion(n == 0); return empty(); }
00143     bool operator!=(Nullptr_t CGAL_assertion_code(n)) const
00144     { CGAL_assertion(n == 0); return !empty(); }
00145 #endif // CGAL_NO_DEPRECATED_CODE
00146 
00147 };
00148 
00149 
00150 #ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE
00151 template <class T>
00152 inline
00153 Object
00154 make_object(T && t)
00155 {
00156     return Object(std::forward<T>(t), Object::private_tag());
00157 }
00158 #else
00159 template <class T>
00160 inline
00161 Object
00162 make_object(const T& t)
00163 {
00164     return Object(t, Object::private_tag());
00165 }
00166 #endif
00167 
00168 template <class T>
00169 inline
00170 bool
00171 assign(T& t, const Object& o)
00172 {
00173     return o.assign(t);
00174 }
00175 
00176 
00177 struct Bad_object_cast
00178   : public std::bad_cast
00179 {
00180     virtual const char * what() const throw()
00181     {
00182         return "CGAL::bad_object_cast: "
00183                "failed conversion using CGAL::object_cast";
00184     }
00185 };
00186 
00187 
00188 template <class T>
00189 inline
00190 const T * object_cast(const Object * o)
00191 {
00192     const Wrapper<T> *wp = dynamic_cast<const Wrapper<T> *>(o->Ptr());
00193     if (wp == NULL)
00194         return NULL;
00195     return static_cast<const T*>(wp->object_ptr());
00196 }
00197 
00198 template <class T>
00199 inline
00200 T object_cast(const Object & o)
00201 {
00202     const T * result = object_cast<T>(&o);
00203     if (!result)
00204         throw Bad_object_cast();
00205     return *result;
00206 }
00207 
00208 CGAL_END_NAMESPACE
00209 
00210 #endif // CGAL_OBJECT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines