BWAPI
|
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