diff --git a/src/NCollection/FILES b/src/NCollection/FILES index ba2ea4ebe3..546ac07af5 100755 --- a/src/NCollection/FILES +++ b/src/NCollection/FILES @@ -72,7 +72,6 @@ NCollection_SparseArrayBase.cxx NCollection_CellFilter.hxx NCollection_CellFilterNDim.hxx NCollection_Handle.hxx -NCollection_Handle.cxx NCollection_Comparator.hxx NCollection_QuickSort.hxx @@ -88,3 +87,4 @@ NCollection_Vec4.hxx NCollection_Mat4.hxx NCollection_StlIterator.hxx +NCollection_Shared.hxx diff --git a/src/NCollection/NCollection_DefineHSequence.hxx b/src/NCollection/NCollection_DefineHSequence.hxx index 153ddc8f41..fbdf53882c 100644 --- a/src/NCollection/NCollection_DefineHSequence.hxx +++ b/src/NCollection/NCollection_DefineHSequence.hxx @@ -25,7 +25,6 @@ // Declaration of Sequence class managed by Handle #define DEFINE_HSEQUENCE(HClassName, _SequenceType_) \ -DEFINE_STANDARD_HANDLE (HClassName, MMgt_TShared) \ class HClassName : public _SequenceType_, public MMgt_TShared { \ public: \ DEFINE_STANDARD_ALLOC \ @@ -44,7 +43,8 @@ class HClassName : public _SequenceType_, public MMgt_TShared { \ _SequenceType_::Append (theOther->ChangeSequence()); \ } \ DEFINE_STANDARD_RTTI (HClassName, MMgt_TShared) \ -}; +}; \ +DEFINE_STANDARD_HANDLE (HClassName, MMgt_TShared) #define IMPLEMENT_HSEQUENCE(HClassName) diff --git a/src/NCollection/NCollection_Handle.cxx b/src/NCollection/NCollection_Handle.cxx deleted file mode 100644 index 3edeefa226..0000000000 --- a/src/NCollection/NCollection_Handle.cxx +++ /dev/null @@ -1,16 +0,0 @@ -// Created on: 2009-01-30 -// Created by: Andrey BETENEV (abv) -// Copyright (c) 2009-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include diff --git a/src/NCollection/NCollection_Handle.hxx b/src/NCollection/NCollection_Handle.hxx index 8bf7844741..ae406e1a2b 100644 --- a/src/NCollection/NCollection_Handle.hxx +++ b/src/NCollection/NCollection_Handle.hxx @@ -74,17 +74,23 @@ class NCollection_Handle : public Handle(Standard_Transient) : Handle(Standard_Transient) (theObject ? new Ptr (theObject) : 0) {} //! Cast handle to contained type - T* operator -> () { return ((Ptr*)ControlAccess())->myPtr; } + T* get () { return ((Ptr*)Handle(Standard_Transient)::get())->myPtr; } + + //! Cast handle to contained type + const T* get () const { return ((Ptr*)Handle(Standard_Transient)::get())->myPtr; } + + //! Cast handle to contained type + T* operator -> () { return get(); } //! Cast handle to contained type - const T* operator -> () const { return ((Ptr*)ControlAccess())->myPtr; } + const T* operator -> () const { return get(); } //! Cast handle to contained type - T& operator * () { return *((Ptr*)ControlAccess())->myPtr; } + T& operator * () { return *get(); } //! Cast handle to contained type - const T& operator * () const { return *((Ptr*)ControlAccess())->myPtr; } - + const T& operator * () const { return *get(); } + //! Downcast arbitrary Handle to the argument type if contained //! object is Handle for this type; returns null otherwise static NCollection_Handle DownCast (const Handle(Standard_Transient)& theOther) diff --git a/src/NCollection/NCollection_Shared.hxx b/src/NCollection/NCollection_Shared.hxx new file mode 100644 index 0000000000..446a0ccfec --- /dev/null +++ b/src/NCollection/NCollection_Shared.hxx @@ -0,0 +1,62 @@ +// Created on: 2015-06-26 +// Created by: Andrey Betenev +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef NCollection_Shared_HeaderFile +#define NCollection_Shared_HeaderFile + +#include + +//! Template defining a class derived from the specified base class and +//! Standard_Transient, and supporting OCCT RTTI. +//! +//! This provides possibility to use Handes for types not initially intended +//! to be dynamically allocated. +//! +//! Current limitation is that only copy and constructors with 1-3 arguments are defined, +//! calling those of the argument class (default constructor must be available). +//! It can be improved when perfect forwarding of template arguments is supported +//! by all compilers used for OCCT. +//! +//! The intent is similar to std::make_shared<> in STL, except that this +//! implementation defines a separate type. + +template ::value>::type> +class NCollection_Shared : public Standard_Transient, public T +{ +public: + DEFINE_STANDARD_ALLOC + DEFINE_NCOLLECTION_ALLOC + + //! Default constructor + NCollection_Shared () {} + + //! Constructor with single argument + template + NCollection_Shared (T1 arg1) : T(arg1) {} + + //! Constructor with two arguments + template + NCollection_Shared (T1 arg1, T2 arg2) : T(arg1, arg2) {} + +/* this could work... + //! Forwarding constructor + template + NCollection_Shared (Args&&... args) + : T (std::forward(args)...) + {} +*/ +}; + +#endif diff --git a/src/Standard/FILES b/src/Standard/FILES index ad50300495..33e845102e 100755 --- a/src/Standard/FILES +++ b/src/Standard/FILES @@ -11,10 +11,6 @@ Standard_JmpBuf.hxx Standard_CMPLRS.edl Standard_Copy.tcl Standard_WOKSteps.edl -Handle_Standard_Persistent.hxx -Handle_Standard_Persistent.cxx -Handle_Standard_Transient.cxx -Handle_Standard_Transient.hxx Standard_Address.hxx Standard_Boolean.hxx Standard_Byte.hxx @@ -27,12 +23,12 @@ Standard_Character.hxx Standard_ExtCharacter.hxx Standard_ExtString.cxx Standard_ExtString.hxx -Standard_HashCode.cxx +Standard_Handle.hxx Standard_IStream.hxx Standard_Integer.hxx Standard_Macro.hxx Standard_OStream.hxx -Standard_Persistent_proto.hxx +Standard_Persistent.hxx Standard_PrimitiveTypes.hxx Standard_Real.cxx Standard_Real.hxx @@ -43,8 +39,6 @@ Standard_ShortReal.hxx Standard_Stream.hxx Standard_Time.hxx Standard_Transient.hxx -Standard_Transient.cxx -Standard_Transient_proto.hxx Standard_TypeDef.hxx Standard_Type.hxx Standard_Type.cxx diff --git a/src/Standard/Handle_Standard_Persistent.cxx b/src/Standard/Handle_Standard_Persistent.cxx deleted file mode 100644 index e1c10af8be..0000000000 --- a/src/Standard/Handle_Standard_Persistent.cxx +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 1998-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - diff --git a/src/Standard/Handle_Standard_Persistent.hxx b/src/Standard/Handle_Standard_Persistent.hxx deleted file mode 100644 index 20dc6f5d2d..0000000000 --- a/src/Standard/Handle_Standard_Persistent.hxx +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 1998-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//============================================================================ -// Title : Handle_Standard_Persistent.hxx -// Role : This file just include -//============================================================================ - -#ifndef _Handle_Standard_Persistent_HeaderFile -#define _Handle_Standard_Persistent_HeaderFile - -#include -#include - -DEFINE_STANDARD_HANDLE(Standard_Persistent, Standard_Transient) - -Standard_EXPORT Standard_Integer HashCode(const Handle(Standard_Persistent)&, const Standard_Integer); - -#endif diff --git a/src/Standard/Handle_Standard_Transient.cxx b/src/Standard/Handle_Standard_Transient.cxx deleted file mode 100644 index efb2d4258d..0000000000 --- a/src/Standard/Handle_Standard_Transient.cxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 1998-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include -#include - -//============================================================================ - -void Handle(Standard_Transient)::Dump(Standard_OStream& out) const -{ - out << Access(); -} - -//============================================================================ - -void Handle(Standard_Transient)::Assign (const Standard_Transient *anItem) -{ - Standard_Transient *anIt = (Standard_Transient*)anItem; - if ( anIt == entity ) return; - EndScope(); - entity = anIt; - BeginScope(); -} - -//============================================================================ - -void Handle(Standard_Transient)::BeginScope() -{ - if (entity != 0) - { - Standard_Atomic_Increment (&entity->count); - } -} - -//============================================================================ - -void Handle(Standard_Transient)::EndScope() -{ - if (entity == 0) - return; - if (Standard_Atomic_Decrement (&entity->count) == 0) - entity->Delete(); - entity = 0; -} diff --git a/src/Standard/Handle_Standard_Transient.hxx b/src/Standard/Handle_Standard_Transient.hxx deleted file mode 100644 index 1ca48bcd24..0000000000 --- a/src/Standard/Handle_Standard_Transient.hxx +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright (c) 1998-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _Handle_Standard_Transient_HeaderFile -#define _Handle_Standard_Transient_HeaderFile - -#include -#include -#include -#include - -#ifdef _WIN32 -// Disable the warning "conversion from 'unsigned int' to Standard_Transient *" -#pragma warning (push) -#pragma warning (disable:4312) -#endif - -class Handle_Standard_Transient; - -Standard_EXPORT Standard_Integer HashCode(const Handle(Standard_Transient)& ,const Standard_Integer); - -/** - * Base class for hierarchy of smart pointers (Handles) for Transient - * objects. Uses reference counting technique to control life time - * of the referred object. - * - * Note that Handle should never be initialized by pointer to object - * created in the stack; only dinamically allocated pointers shall be used. - */ - -class Handle(Standard_Transient) -{ -public: - - // Public methods - - //! Empty constructor - Handle(Standard_Transient) () - : entity(0) - { - } - - //! Constructor from pointer to new object - Handle(Standard_Transient) (const Standard_Transient *anItem) - : entity ( (Standard_Transient*)anItem ) - { - BeginScope(); - } - - //! Copy constructor - Handle(Standard_Transient) (const Handle(Standard_Transient)& aTid) - : entity ( aTid.entity ) - { - BeginScope(); - } - - //! Destructor - ~Handle(Standard_Transient)() - { - EndScope(); - } - - //! Assignment operator - Handle(Standard_Transient)& operator=(const Handle(Standard_Transient)& aHandle) - { - Assign(aHandle.Access()); - return *this; - } - - //! Assignment operator - Handle(Standard_Transient)& operator=(const Standard_Transient* anItem) - { - Assign(anItem); - return *this; - } - - //! Nullify the handle - void Nullify() - { - EndScope(); - } - - //! Check for being null - Standard_Boolean IsNull() const - { - return entity == 0; - } - - //! Returns pointer to referred object - Standard_Transient* Access() - { - return entity; - } - - //! Returns const pointer to referred object - const Standard_Transient* Access() const - { - return entity; - } - - //! Cast to pointer to referred object - operator Standard_Transient*() - { - return entity; - } - - //! Cast to const pointer to referred object - operator const Standard_Transient*() const - { - return entity; - } - - //! Member access operator (note non-const) - Standard_Transient* operator->() const - { - return entity; - } - - //! STL-style member accessor - Standard_Transient* get() const - { - return entity; - } - - //! Dereferencing operator - Standard_Transient& operator*() - { - return *entity; - } - - //! Const dereferencing operator - const Standard_Transient& operator*() const - { - return *entity; - } - - //! Check for equality - int operator==(const Handle(Standard_Transient)& right) const - { - return entity == right.entity; - } - - //! Check for equality - int operator==(const Standard_Transient *right) const - { - return entity == right; - } - - //! Check for equality - friend bool operator==(const Standard_Transient *left, const Handle(Standard_Transient)& right) - { - return left == right.entity; - } - - //! Check for inequality - bool operator!=(const Handle(Standard_Transient)& right) const - { - return entity != right.entity; - } - - //! Check for inequality - bool operator!=(const Standard_Transient *right) const - { - return entity != right; - } - - //! Check for inequality - friend bool operator!=(const Standard_Transient *left, const Handle(Standard_Transient)& right) - { - return left != right.entity; - } - - //! Down casting operator; dummy provided for consistency with other classes - //! (descendants) - static const Handle(Standard_Transient)& DownCast(const Handle(Standard_Transient)& AnObject) - { - return AnObject; - } - - //! Dump pointer to a referred object to a stream - Standard_EXPORT void Dump(Standard_OStream& out) const; - -protected: - // Protected methods for descendants - - //! Returns non-const pointer to referred object - Standard_Transient* ControlAccess() const - { - return entity; - } - - //! Assignment - Standard_EXPORT void Assign (const Standard_Transient *anItem); - -private: - // Private methods - - //! Increment reference counter of referred object - Standard_EXPORT void BeginScope(); - - //! Decrement reference counter and if 0, destroy referred object - Standard_EXPORT void EndScope(); - -public: - - DEFINE_STANDARD_ALLOC - -private: - // Field - Standard_Transient *entity; -}; - -//! Function in global scope to check handles for equality. -//! Will be used with standard OCCT collections like NCollection_DataMap within NCollection_DefaultHasher -//! when there are no specialization defined for concrete type. -//! Notice that this implementation compares only pointers to objects! -inline Standard_Boolean IsEqual (const Handle(Standard_Transient)& theFirst, - const Handle(Standard_Transient)& theSecond) -{ - return theFirst == theSecond; -} - -#ifdef _WIN32 -#pragma warning (pop) -#endif - -#endif diff --git a/src/Standard/Standard.cdl b/src/Standard/Standard.cdl index af8a7dfa88..e3cdc94e43 100644 --- a/src/Standard/Standard.cdl +++ b/src/Standard/Standard.cdl @@ -65,7 +65,7 @@ is class GUID; - deferred class Persistent ; + imported deferred class Persistent ; imported deferred class Transient ; imported transient class Type; -- inherits Transient diff --git a/src/Standard/Standard_Copy.tcl b/src/Standard/Standard_Copy.tcl index a3fb71a56d..fb507930d9 100644 --- a/src/Standard/Standard_Copy.tcl +++ b/src/Standard/Standard_Copy.tcl @@ -25,8 +25,6 @@ proc Standard_Copy:HandleInputFile { ID } { scan $ID "%\[^:\]:%\[^:\]:%\[^:\]" unit type name switch $name { - Handle_Standard_Transient.hxx {return 1;} - Handle_Standard_Persistent.hxx {return 1;} Standard_Transient.hxx {return 1;} Standard_Persistent.hxx {return 1;} default { @@ -42,20 +40,10 @@ proc Standard_Copy:Execute { unit args } { foreach file $args { scan $file "%\[^:\]:%\[^:\]:%\[^:\]" Unit type name + set source [woklocate -p Standard:source:$name [wokinfo -N $unit]] - if { $name == "Standard_Persistent.hxx" || $name == "Standard_Persistent_objy.ddl"} { - set source [woklocate -p Standard:source:Standard_Persistent_proto.hxx [wokinfo -N $unit]] - } else { - set source [woklocate -p Standard:source:$name [wokinfo -N $unit]] - } - - if { $name == "lctlprt.dll" || $name == "lctlprt.lib" || $name == "lmgr32.dll" || $name == "rtk.lib" || $name == "rtk.dll" } { - set vistarget [woklocate -p Standard:library:$name [wokinfo -N $unit]] - set target [wokinfo -p library:$name $unit] - } else { - set vistarget [woklocate -p Standard:pubinclude:$name [wokinfo -N $unit]] - set target [wokinfo -p pubinclude:$name $unit] - } + set vistarget [woklocate -p Standard:pubinclude:$name [wokinfo -N $unit]] + set target [wokinfo -p pubinclude:$name $unit] if { [catch {eval exec "cmp $source $vistarget"} ] } { msgprint -i -c "Standard_Copy::Execute" "Copy $source to $target" diff --git a/src/Standard/Standard_DefineHandle.hxx b/src/Standard/Standard_DefineHandle.hxx index 37d53e9a52..c33381ac00 100644 --- a/src/Standard/Standard_DefineHandle.hxx +++ b/src/Standard/Standard_DefineHandle.hxx @@ -15,76 +15,17 @@ #ifndef _Standard_DefineHandle_HeaderFile #define _Standard_DefineHandle_HeaderFile -#include - //! @file -//! This file provides low-level helper macros for definition of OCCT handles and types. -//! It is not to be included in the user code directly; include Standard_Type.hxx instead. +//! This file provides obsolete low-level helper macros used to define OCCT handles and types, +//! for compatibility with previous versions of OCCT. +//! Since OCCT 7.0, relevant macros are provided by Standard_Type.hxx and Standard_Handle.hxx. + +#include class Standard_Transient; class Standard_Persistent; class Standard_Type; -// Forward declarations of auxiliary template class for type descriptor instantiation -// and down casting function; defined in Standard_Type.hxx -namespace opencascade { - template class type_instance; - template H1 down_cast (const H2& theObject); -} - -//! Helper macro to get instance of a type descriptor for a class in a legacy way. -#define STANDARD_TYPE(theType) Standard_Type::Instance() - -//! Helper macro to be included in definition of the classes inheriting -//! Standard_Transient to enable use of OCCT RTTI and smart pointers (handles). -#define DEFINE_STANDARD_RTTI(Class,Base) \ -public: \ - typedef Base base_type; \ - static const char* get_type_name () { return #Class; } \ - virtual const Handle(Standard_Type)& DynamicType() const { return STANDARD_TYPE(Class); } - -//! Define OCCT Handle for a class C1 inheriting C2, -//! with BC being a root of the hierarchy -#define DEFINE_STANDARD_HANDLECLASS(C1,C2,BC) \ -class C1; \ -class Handle(C1) : public Handle(C2) { \ -public: \ - typedef C1 element_type;\ - \ - Handle(C1)() {} \ - Handle(C1)(const Handle(C1)& aHandle) : Handle(C2)(aHandle) {} \ - Handle(C1)(const C1* anItem) : Handle(C2)((C2 *)anItem) {} \ - \ - Handle(C1)& operator=(const Handle(C1)& aHandle) \ - { \ - Assign(aHandle.Access()); \ - return *this; \ - } \ - Handle(C1)& operator=(const C1* anItem) \ - { \ - Assign((BC*)anItem); \ - return *this; \ - } \ - \ - C1& operator*() const { return *(C1 *)ControlAccess(); } \ - C1* operator->() const { return (C1 *)ControlAccess(); } \ - C1* get() const { return (C1 *)ControlAccess(); } \ - \ - template \ - static Handle(C1) DownCast(const HBC& theObject) \ - { \ - return opencascade::down_cast (theObject); \ - } \ -}; - -// TRANSIENT -// -#define DEFINE_STANDARD_HANDLE(C1,C2) DEFINE_STANDARD_HANDLECLASS(C1,C2,Standard_Transient) - -// PERSISTENT -// -#define DEFINE_STANDARD_PHANDLE(C1,C2) DEFINE_STANDARD_HANDLECLASS(C1,C2,Standard_Persistent) - // Obsolete macros kept for compatibility #define IMPLEMENT_DOWNCAST(C1,BC) #define IMPLEMENT_STANDARD_HANDLE(C1,C2) diff --git a/src/Standard/Standard_Handle.hxx b/src/Standard/Standard_Handle.hxx new file mode 100644 index 0000000000..4ada0c8a4a --- /dev/null +++ b/src/Standard/Standard_Handle.hxx @@ -0,0 +1,267 @@ +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Standard_Handle_HeaderFile +#define _Standard_Handle_HeaderFile + +#include +#include +#include + +#include + +class Standard_Transient; + +namespace opencascade { + + //! Intrusive smart pointer for use with Standard_Transient class and its descendants. + //! + //! This class is similar to boost::intrusive_ptr<>, with additional + //! feature historically supported by Handles in OCCT: + //! it has type conversion to const reference to handle to the base types, + //! which allows it to be passed by reference + //! in functions accepring reference to handle to base class. + template + class handle + { + public: + //! STL-compliant typedef of contained type + typedef T element_type; + + public: + + //! Empty constructor + handle () : entity(0) {} + + //! Constructor from pointer to new object + handle (const T *thePtr) : entity(const_cast(thePtr)) + { + BeginScope(); + } +/* TODO: uncomment and remove const from method above + //! Constructor from const pointer to new object; + //! will raise exception if object's reference counter is zero + explicit handle (const T *thePtr) : entity(thePtr->This()) + { + BeginScope(); + } +*/ + //! Copy constructor + handle (const handle& theHandle) : entity(theHandle.entity) + { + BeginScope(); + } + + //! Destructor + ~handle () + { + EndScope(); + } + + //! Nullify the handle + void Nullify() + { + EndScope(); + } + + //! Check for being null + bool IsNull() const { return entity == 0; } + + //! Reset by new pointer + void reset (T* thePtr) + { + Assign (thePtr); + } + + //! Assignment operator + handle& operator= (const handle& theHandle) + { + Assign (theHandle.entity); + return *this; + } + + //! Assignment to pointer + handle& operator= (const T* thePtr) + { + Assign (const_cast(thePtr)); + return *this; + } +/* uncomment along with constructor + //! Assignment to pointer to const object + handle& operator= (const T* thePtr) + { + Assign (thePtr->This()); + return *this; + } +*/ + //! STL-like cast to pointer to referred object + const T* get () const { return static_cast(this->entity); } + + //! STL-like cast to pointer to referred object + T* get () { return static_cast(this->entity); } + + //! Member access operator (note non-const) + T* operator-> () const { return static_cast(this->entity); } + + //! Dereferencing operator + T& operator* () { return *get(); } + + //! Const dereferencing operator + const T& operator*() const { return *get(); } + + //! Check for equality + template + bool operator== (const handle& theHandle) const + { + return this->entity == theHandle.entity; + } + + //! Check for equality + bool operator== (const Standard_Transient *thePtr) const + { + return this->entity == thePtr; + } + + //! Check for equality + friend bool operator== (const Standard_Transient *left, const handle& right) + { + return left == right.entity; + } + + //! Check for inequality + template + bool operator!= (const handle& theHandle) const + { + return this->entity != theHandle.entity; + } + + //! Check for inequality + bool operator!= (const Standard_Transient *thePtr) const + { + return this->entity != thePtr; + } + + //! Check for inequality + friend bool operator!= (const Standard_Transient *left, const handle& right) + { + return left != right.entity; + } + + //! Down casting operator + template + static handle DownCast (const handle& theObject) + { + return handle (dynamic_cast(const_cast(theObject.get()))); + } + + //! Down casting operator + template + static handle DownCast (const T2* thePtr) + { + return handle (dynamic_cast(const_cast(thePtr))); + } + +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) || (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3) + + //! Upcast to const reference to base type. + template ::value>::type> + operator const handle& () const + { + return reinterpret_cast&>(*this); + } + + //! Upcast to non-const reference to base type. + //! NB: this cast can be dangerous, see #26377 + template ::value>::type> + operator handle& () + { + return reinterpret_cast&>(*this); + } + +#else /* fallback version for compilers not supporting default arguments of function templates (VC10, VC11, GCC below 4.3) */ + + //! Upcast to const reference to base type. + //! NB: this implementation will cause ambiguity errors on calls to overloaded + //! functions accepting handles to different types, since compatibility is + //! checked in the cast code rather than ensured by SFINAE (possible with C++11) + template + operator const handle& () const + { + // error "type is not a member of enable_if" will be generated if T2 is not sub-type of T + // (handle is being cast to const& to handle of non-base type) + return reinterpret_cast::value, const handle&>::type>(*this); + } + + //! Upcast to non-const reference to base type. + //! NB: this cast can be dangerous, see #26377 + template + operator handle& () + { + // error "type is not a member of enable_if" will be generated if T2 is not sub-type of T + // (handle is being cast to const& to handle of non-base type) + return reinterpret_cast::value, handle&>::type>(*this); + } + +#endif + + private: + + //! Assignment + void Assign (Standard_Transient *thePtr) + { + if (thePtr == entity) + return; + EndScope(); + entity = thePtr; + BeginScope(); + } + + //! Increment reference counter of referred object + void BeginScope() + { + if (entity != 0) + entity->IncrementRefCounter(); + } + + //! Decrement reference counter and if 0, destroy referred object + void EndScope() + { + if (entity != 0 && entity->DecrementRefCounter() == 0) + entity->Delete(); + entity = 0; + } + + template friend class handle; + + private: + Standard_Transient* entity; + }; + +} // namespace opencascade + +//! Define Handle() macro +#define Handle(Class) opencascade::handle + +//! Global method HashCode(), for use in hash maps +template +inline Standard_Integer HashCode (const Handle(T)& theHandle, const Standard_Integer theUpper) +{ + return ::HashCode (const_cast(static_cast(theHandle.get())), theUpper); +} + +//! For compatibility with previous versions of OCCT, defines typedef opencascade::handle Handle_Class +#define DEFINE_STANDARD_HANDLECLASS(C1,C2,BC) typedef Handle(C1) Handle_##C1; +#define DEFINE_STANDARD_HANDLE(C1,C2) DEFINE_STANDARD_HANDLECLASS(C1,C2,Standard_Transient) +#define DEFINE_STANDARD_PHANDLE(C1,C2) DEFINE_STANDARD_HANDLECLASS(C1,C2,Standard_Persistent) + +#endif diff --git a/src/Standard/Standard_HashCode.cxx b/src/Standard/Standard_HashCode.cxx deleted file mode 100644 index 5e94deceac..0000000000 --- a/src/Standard/Standard_HashCode.cxx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 1998-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include -#include -#include -#include - -//============================================================================ -Standard_EXPORT Standard_Integer HashCode (const Handle(Standard_Transient)& me, - const Standard_Integer Upper ) -{ - Standard_RangeError_Raise_if (Upper < 1, - "Try to apply HashCode method " - "with negative or null argument."); - - const Standard_Integer I = (Standard_Integer) ptrdiff_t(me.operator->()); - return HashCode( I , Upper ) ; -} - -//============================================================================ -Standard_EXPORT Standard_Integer HashCode(const Handle(Standard_Persistent)& me, - const Standard_Integer Upper ) -{ - Standard_RangeError_Raise_if (Upper < 1, - "Try to apply HashCode method " - "with negative or null argument."); - - const Standard_Integer I = (Standard_Integer) ptrdiff_t(me.operator->()); - return HashCode( I , Upper) ; -} - diff --git a/src/Standard/Standard_Macro.hxx b/src/Standard/Standard_Macro.hxx index dd3ede3830..78faf57b2e 100644 --- a/src/Standard/Standard_Macro.hxx +++ b/src/Standard/Standard_Macro.hxx @@ -19,9 +19,6 @@ #ifndef _Standard_Macro_HeaderFile # define _Standard_Macro_HeaderFile -// Standard OCC macros: Handle(), STANDARD_TYPE() -# define Handle(ClassName) Handle_##ClassName - #if defined(__cplusplus) && (__cplusplus >= 201100L) // part of C++11 standard #define Standard_OVERRIDE override diff --git a/src/Standard/Standard_Persistent.cdl b/src/Standard/Standard_Persistent.cdl index 091ce8dfc2..f100094bb4 100644 --- a/src/Standard/Standard_Persistent.cdl +++ b/src/Standard/Standard_Persistent.cdl @@ -14,108 +14,19 @@ -- Alternatively, this file may be used under the terms of Open CASCADE -- commercial license or contractual agreement. -deferred class Persistent from Standard +imported deferred class Persistent from Standard +inherits Transient from Standard - ---Purpose: - -- The root of the entire persistent class hierarchy. - -- - -- Persistence is the ability to create objects which - -- outlive the application process. - -- Objects stored in the database must be instances - -- of a Persistent-derived class. - -- The collection of persistent classes used by an - -- application constitute its application data schema. - -- - -- Open CASCADE provides persistent classes to describe: - -- - ASCII (normal 8 bit character type) and - -- Unicode (16 bit character type) strings, - -- - arrays of persistent data, - -- - geometric data structures, - -- - topological data structures. - -- - -- The user can enrich this set of persistent classes by describing - -- his own persistent data structures inheriting from Persistent - -- for use in a store and retrieve programming context. - -- - -- Warning: - -- - -- Persistent objects are manipulated in programs by handles. - -- A handle to a persistent object behaves like - -- a pointer to the entire database address space. - -- In using such a handle, you transparently operate on the object - -- in the database, providing that you do this inside a transaction. - -- - -- However "Persistent Programming" (i.e. the programming - -- technique whereby the application operates on persistent - -- objects, that is, directly in the database, within a transaction) - -- is not supported by Open CASCADE. - -uses - Type from Standard - ,Boolean from Standard - ,OId from Standard - +uses +Transient + +---Purpose: +-- Root of "persistent" classes, a legacy support of +-- object oriented databases, now outdated. + is - Delete (me: mutable) is virtual; - ---Purpose: Deletes this object. - - - DynamicType (me) returns Type is virtual; - ---Purpose: - -- Returns the type object representing the actual type of the object. - -- There is one type object per Persistent-derived class. - -- - -- Example: - -- - -- Handle(Standard_Persistent) p; - -- Handle(Standard_Type) t; - -- p = new PGeom_CartesianPoint(0.,0.,0.); - -- t = STANDARD_TYPE(PGeom_CartesianPoint); - -- assert(p->DynamicType() == t); - - IsInstance (me; TheType : Type) returns Boolean is static; - ---Purpose: - -- Returns true if the actual type of the object is equal to the given type. - -- - -- Example: - -- - -- Handle(Standard_Persistent) p; - -- Handle(Standard_Type) t; - -- p = new PGeom_CartesianPoint(0.,0.,0.); - -- t = STANDARD_TYPE(PGeom_CartesianPoint); - -- assert(p->IsInstance(t)); - -- - -- Warning: - -- - -- For most purposes it is better to use IsKind because IsInstance - -- rejects objects being subtype of the given type. - - IsKind (me; TheType : Type) returns Boolean - ---Purpose: - -- Returns true if is an instance of or an - -- instance of any class that inherits from . - -- All persistent objects are a kind of Object class. - -- - -- Example: - -- - -- Handle(Standard_Persistent) p; - -- Handle(Standard_Type) tp, tt; - -- p = new PGeom_CartesianPoint(0.,0.,0.); - -- tp = STANDARD_TYPE(PGeom_CartesianPoint); - -- tt = STANDARD_TYPE(Standard_Persistent); - -- assert(p->IsKind(tp)); - -- assert(p->IsKind(tt)); - is static; - - This (me) returns Persistent - ---Purpose: Returns a handle on the object. - -- This method is useful only in constructors of persistent - -- objects when you need a handle on the object being constructed. - -- It guarantees that, whatever the underlying database - -- you are using, the object will not be swapped out - -- during its construction. - is static protected; + Initialize returns Persistent; end Persistent from Standard; diff --git a/src/Standard/Standard_Persistent_proto.hxx b/src/Standard/Standard_Persistent.hxx similarity index 57% rename from src/Standard/Standard_Persistent_proto.hxx rename to src/Standard/Standard_Persistent.hxx index 499536e35a..7bc372e676 100644 --- a/src/Standard/Standard_Persistent_proto.hxx +++ b/src/Standard/Standard_Persistent.hxx @@ -12,38 +12,27 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#ifndef _Standard_Persistent_proto_HeaderFile -#define _Standard_Persistent_proto_HeaderFile +#ifndef _Standard_Persistent_HeaderFile +#define _Standard_Persistent_HeaderFile -#include #include -#include - -class Standard_Type; -class Handle_Standard_Type; -class Handle_Standard_Persistent; -class Standard_Type; - -class Storage_stCONSTclCOM; +//! Root of "persistent" classes, a legacy support of +//! object oriented databases, now outdated. class Standard_Persistent : public Standard_Transient { -friend class Handle(Standard_Persistent); -friend class Storage_Schema; +public: + DEFINE_STANDARD_ALLOC + + Standard_Persistent() : _typenum(0), _refnum(0) {} + + DEFINE_STANDARD_RTTI(Standard_Persistent,Standard_Transient) private: Standard_Integer _typenum; Standard_Integer _refnum; -public: - - Standard_Persistent& operator= (const Standard_Persistent&) { return *this; } - Standard_Persistent() : _typenum(0),_refnum(0) {} - Standard_Persistent(const Standard_Persistent&) : _typenum(0),_refnum(0) {} - Standard_Persistent(const Storage_stCONSTclCOM&) : _typenum(0),_refnum(0) {} - DEFINE_STANDARD_RTTI(Standard_Persistent,Standard_Transient) + friend class Storage_Schema; }; -#include - -#endif +#endif // _Standard_Persistent_HeaderFile diff --git a/src/Standard/Standard_Transient.cxx b/src/Standard/Standard_Transient.cxx index a113a9c75c..4a3aaf312e 100644 --- a/src/Standard/Standard_Transient.cxx +++ b/src/Standard/Standard_Transient.cxx @@ -12,31 +12,22 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include #include +#include +#include +#include +#include + +void Standard_Transient::Delete() const +{ + delete this; +} // -// The Standard_Transient Methods -// - -// DynamicType // const Handle(Standard_Type)& Standard_Transient::DynamicType() const { - return STANDARD_TYPE(Standard_Transient); -} - -// The Method This -// -Handle(Standard_Transient) Standard_Transient::This() const -{ - return Handle(Standard_Transient)(this); -} - -// Empty Destructor -// -Standard_Transient::~Standard_Transient() -{ + return opencascade::type_instance::get(); } // @@ -67,7 +58,23 @@ Standard_Boolean Standard_Transient::IsKind (const Standard_CString theTypeName) return DynamicType()->SubType ( theTypeName ); } -void Standard_Transient::Delete() const -{ - delete((Standard_Transient *)this); +// +// +Standard_Transient* Standard_Transient::This() const +{ + if (GetRefCount() == 0) + Standard_ProgramError::Raise ("Attempt to create handle to object created in stack, not yet constructed, or destroyed"); + return const_cast (this); +} + +// Increment reference counter +void Standard_Transient::IncrementRefCounter() const +{ + Standard_Atomic_Increment (&count); +} + +// Decrement reference counter +Standard_Integer Standard_Transient::DecrementRefCounter() const +{ + return Standard_Atomic_Decrement (&count); } diff --git a/src/Standard/Standard_Transient.hxx b/src/Standard/Standard_Transient.hxx index fdbbd43100..e4ead07969 100644 --- a/src/Standard/Standard_Transient.hxx +++ b/src/Standard/Standard_Transient.hxx @@ -15,9 +15,100 @@ #ifndef _Standard_Transient_HeaderFile #define _Standard_Transient_HeaderFile -#include +#include +#include #include -#include -//#include + +class Standard_Type; + +namespace opencascade { + template class handle; +} + +//! Abstract class which forms the root of the entire +//! Transient class hierarchy. + +class Standard_Transient +{ +public: + // Standard OCCT memory allocation stuff + DEFINE_STANDARD_ALLOC + +public: + + //! Empty constructor + Standard_Transient() : count(0) {} + + //! Copy constructor -- does nothing + Standard_Transient (const Standard_Transient&) : count(0) {} + + //! Assignment operator, needed to avoid copying reference counter + Standard_Transient& operator= (const Standard_Transient&) { return *this; } + + //! Destructor must be virtual + virtual ~Standard_Transient() {} + + //! Memory deallocator for transient classes + Standard_EXPORT virtual void Delete() const; + +public: + //!@name Support of run-time type information (RTTI) + + typedef void base_type; + + static const char* get_type_name () { return "Standard_Transient"; } + + //! Returns a type information object about this object. + Standard_EXPORT virtual const opencascade::handle& DynamicType() const; + + //! Returns a true value if this is an instance of Type. + Standard_EXPORT Standard_Boolean IsInstance(const opencascade::handle& theType) const; + + //! Returns a true value if this is an instance of TypeName. + Standard_EXPORT Standard_Boolean IsInstance(const Standard_CString theTypeName) const; + + //! Returns true if this is an instance of Type or an + //! instance of any class that inherits from Type. + //! Note that multiple inheritance is not supported by OCCT RTTI mechanism. + Standard_EXPORT Standard_Boolean IsKind(const opencascade::handle& theType) const; + + //! Returns true if this is an instance of TypeName or an + //! instance of any class that inherits from TypeName. + //! Note that multiple inheritance is not supported by OCCT RTTI mechanism. + Standard_EXPORT Standard_Boolean IsKind(const Standard_CString theTypeName) const; + + //! Returns non-const pointer to this object (like const_cast). + //! For protection against creating handle to objects allocated in stack + //! or call from constructor, it will raise exception Standard_ProgramError + //! if reference counter is zero. + Standard_EXPORT Standard_Transient* This() const; + +public: + //!@name Reference counting, for use by handle<> + + //! Get the reference counter of this object + Standard_EXPORT Standard_Integer GetRefCount() const { return count; } + + //! Increments the reference counter of this object + Standard_EXPORT void IncrementRefCounter() const; + + //! Decrements the reference counter of this object; + //! returns the decremented value + Standard_EXPORT Standard_Integer DecrementRefCounter() const; + +private: + + //! Reference counter + mutable volatile Standard_Integer count; +}; + +//! Global method HashCode(), for use in hash maps +inline Standard_Integer HashCode (const Standard_Transient* theObject, const Standard_Integer theUpper) +{ + return ::HashCode ((Standard_Address*)theObject, theUpper); +} + +//! Definition of Handle_Standard_Transient as typedef for compatibility +typedef opencascade::handle Handle_Standard_Transient; #endif diff --git a/src/Standard/Standard_Transient_proto.hxx b/src/Standard/Standard_Transient_proto.hxx deleted file mode 100644 index f114bc4aaf..0000000000 --- a/src/Standard/Standard_Transient_proto.hxx +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 1998-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _Standard_Transient_proto_HeaderFile -#define _Standard_Transient_proto_HeaderFile - -#include -#include -#include - -class Handle_Standard_Transient; -class Standard_Type; -class Handle_Standard_Type; - -//! Abstract class which forms the root of the entire -//! Transient class hierarchy. - -class Standard_Transient -{ - //---- uses the friend Standard_Transient class - friend class Handle(Standard_Transient); - -public: - - DEFINE_STANDARD_ALLOC - - //! Definition of base_type for RTTI (see Standard_Type) - typedef void base_type; - - //! Definition of the class name - static const char* get_type_name () { return "Standard_Transient"; } - -public: - - //! Empty constructor - Standard_Transient() : count(0) {} - - //! Copy constructor -- does nothing - Standard_Transient(const Standard_Transient&) : count(0) {} - - //! Assignment operator, needed to avoid copying reference counter - Standard_Transient& operator= (const Standard_Transient&) { return *this; } - - //! Destructor must be virtual - Standard_EXPORT virtual ~Standard_Transient(); - - //! Memory deallocator for transient classes - Standard_EXPORT virtual void Delete() const; - - //! Returns a type information object about this object. - Standard_EXPORT virtual const Handle_Standard_Type& DynamicType() const; - - //! Returns a true value if this is an instance of Type. - Standard_EXPORT Standard_Boolean IsInstance(const Handle_Standard_Type& theType) const; - - //! Returns a true value if this is an instance of TypeName. - Standard_EXPORT Standard_Boolean IsInstance(const Standard_CString theTypeName) const; - - //! Returns true if this is an instance of Type or an - //! instance of any class that inherits from Type. - //! Note that multiple inheritance is not supported by OCCT RTTI mechanism. - Standard_EXPORT Standard_Boolean IsKind(const Handle_Standard_Type& theType) const; - - //! Returns true if this is an instance of TypeName or an - //! instance of any class that inherits from TypeName. - //! Note that multiple inheritance is not supported by OCCT RTTI mechanism. - Standard_EXPORT Standard_Boolean IsKind(const Standard_CString theTypeName) const; - - //! Returns a Handle which references this object. - //! Must never be called to objects created in stack. - Standard_EXPORT virtual Handle_Standard_Transient This() const; - - //! Get the reference counter of this object. - Standard_EXPORT Standard_Integer GetRefCount() const { return count; } - - private: - - volatile Standard_Integer count; -}; - -#endif diff --git a/src/Standard/Standard_Type.cxx b/src/Standard/Standard_Type.cxx index 6df4754284..5e823851a3 100644 --- a/src/Standard/Standard_Type.cxx +++ b/src/Standard/Standard_Type.cxx @@ -71,8 +71,8 @@ namespace { } } -const Standard_Type* Standard_Type::Register (const char* theSystemName, const char* theName, - Standard_Size theSize, const Handle(Standard_Type)& theParent) +Standard_Type* Standard_Type::Register (const char* theSystemName, const char* theName, + Standard_Size theSize, const Handle(Standard_Type)& theParent) { // Access to registry is protected by mutex; it should not happen often because // instances are cached by Standard_Type::Instance() (one per binary module) diff --git a/src/Standard/Standard_Type.hxx b/src/Standard/Standard_Type.hxx index 2b5c0a1f9c..c9befb8563 100644 --- a/src/Standard/Standard_Type.hxx +++ b/src/Standard/Standard_Type.hxx @@ -16,13 +16,28 @@ #define _Standard_Type_HeaderFile #include -#include +#include #include +#include #include -// Define handle class -DEFINE_STANDARD_HANDLE(Standard_Type, Standard_Transient) +//! Helper macro to get instance of a type descriptor for a class in a legacy way. +#define STANDARD_TYPE(theType) Standard_Type::Instance() + +//! Helper macro to be included in definition of the classes inheriting +//! Standard_Transient to enable use of OCCT RTTI and smart pointers (handles). +#define DEFINE_STANDARD_RTTI(Class,Base) \ +public: \ + typedef Base base_type; \ + static const char* get_type_name () { return #Class; } \ + virtual const Handle(Standard_Type)& DynamicType() const { return STANDARD_TYPE(Class); } + +// forward declaration of type_instance class +namespace opencascade { + template + class type_instance; +} //! This class provides legacy interface (type descriptor) to run-time type //! information (RTTI) for OCCT classes inheriting from Standard_Transient. @@ -94,8 +109,8 @@ public: //! //! Note that this function is intended for use by opencascade::type_instance only. Standard_EXPORT static - const Standard_Type* Register (const char* theSystemName, const char* theName, - Standard_Size theSize, const Handle(Standard_Type)& theParent); + Standard_Type* Register (const char* theSystemName, const char* theName, + Standard_Size theSize, const Handle(Standard_Type)& theParent); //! Destructor removes the type from the registry Standard_EXPORT ~Standard_Type (); @@ -160,17 +175,6 @@ namespace opencascade { template Handle(Standard_Type) type_instance::myInstance (get()); - //! Definition of dynamic cast function for handles - template - H1 down_cast (const H2& theObject) - { - return ! theObject.IsNull() && theObject->IsKind (Standard_Type::Instance()) ? - static_cast (theObject.get()) : 0; -/* alternative implementation using standard C++ RTTI is slower: - return dynamic_cast(theObject.get()); -*/ - } - } //! Operator printing type descriptor to stream @@ -180,4 +184,7 @@ inline Standard_OStream& operator << (Standard_OStream& theStream, const Handle( return theStream; } +//! Definition of Handle_Standard_Type as typedef for compatibility +DEFINE_STANDARD_HANDLE(Standard_Type,Standard_Transient) + #endif // _Standard_Type_HeaderFile