0027111: Add generalized copy constructor in handle class for old compilers
authorabv <abv@opencascade.com>
Sat, 6 Feb 2016 12:26:26 +0000 (15:26 +0300)
committerabv <abv@opencascade.com>
Sat, 20 Feb 2016 07:10:12 +0000 (10:10 +0300)
Copy constructor and assignment operator from handle of derived type is added in handle class.
They are enabled only if macro OCC_HANDLE_NOCASTS is defined, and operators of cast of handle to reference to handle to base type are disabled in that case.

Useless type casts to handle to base type are removed in GC and GCE2d classes.
Code returning reference to handle from function is corrected to return it either by value or as reference to handle of actual type.

44 files changed:
dox/dev_guides/upgrade/upgrade.md
src/AIS/AIS_LocalContext_1.cxx
src/BinDrivers/BinDrivers.cxx
src/BinLDrivers/BinLDrivers.cxx
src/BinTObjDrivers/BinTObjDrivers.cxx
src/BinXCAFDrivers/BinXCAFDrivers.cxx
src/FWOSDriver/FWOSDriver.cxx
src/GC/GC_MakeArcOfCircle.hxx
src/GC/GC_MakeArcOfEllipse.hxx
src/GC/GC_MakeArcOfHyperbola.hxx
src/GC/GC_MakeArcOfParabola.hxx
src/GC/GC_MakeCircle.hxx
src/GC/GC_MakeConicalSurface.hxx
src/GC/GC_MakeCylindricalSurface.hxx
src/GC/GC_MakeEllipse.hxx
src/GC/GC_MakeHyperbola.hxx
src/GC/GC_MakeLine.hxx
src/GC/GC_MakePlane.hxx
src/GC/GC_MakeSegment.hxx
src/GC/GC_MakeTrimmedCone.hxx
src/GC/GC_MakeTrimmedCylinder.hxx
src/GCE2d/GCE2d_MakeArcOfCircle.hxx
src/GCE2d/GCE2d_MakeArcOfEllipse.hxx
src/GCE2d/GCE2d_MakeArcOfHyperbola.hxx
src/GCE2d/GCE2d_MakeArcOfParabola.hxx
src/GCE2d/GCE2d_MakeCircle.hxx
src/GCE2d/GCE2d_MakeEllipse.hxx
src/GCE2d/GCE2d_MakeHyperbola.hxx
src/GCE2d/GCE2d_MakeLine.hxx
src/GCE2d/GCE2d_MakeParabola.hxx
src/GCE2d/GCE2d_MakeSegment.hxx
src/OpenGl/OpenGl_Context.cxx
src/PrsMgr/PrsMgr_Presentation.cxx
src/PrsMgr/PrsMgr_Presentation.hxx
src/Standard/Standard_Handle.hxx
src/TopOpeBRepBuild/TopOpeBRepBuild_LoopSet.cxx
src/TopOpeBRepBuild/TopOpeBRepBuild_LoopSet.hxx
src/TopOpeBRepBuild/TopOpeBRepBuild_PaveSet.cxx
src/TopOpeBRepBuild/TopOpeBRepBuild_PaveSet.hxx
src/XSControl/XSControl_Controller.cxx
src/XmlDrivers/XmlDrivers.cxx
src/XmlLDrivers/XmlLDrivers.cxx
src/XmlTObjDrivers/XmlTObjDrivers.cxx
src/XmlXCAFDrivers/XmlXCAFDrivers.cxx

index cf71429..518f591 100644 (file)
@@ -219,6 +219,8 @@ Handle(Geom_TrimmedCurve) aCurve = new Geom_TrimmedCurve (...);
 func (aCurve); // ambiguity error in VC++ 10
 ~~~~~
 
+Note that this problem does not appear if macro *OCCT_HANDLE_NOCAST* is used, see @ref upgrade_occt700_cdl_nocast "below".
+
 To resolve this ambiguity, change your code so that argument type should correspond exactly to the function signature. 
 In some cases this can be done by using the relevant type for the corresponding variable, like in the example above:
 
@@ -262,6 +264,16 @@ or use variable of the appropriate type:
 Handle(Geom_TrimmedCurve) aC = GC_MakeLine (p, v); // ok
 ~~~~~
 
+With GCC compiler, similar problem appears when const handle to derived type is used to construct handle to base type via assignment (and in some cases in return statement), for instance:
+
+~~~~~
+  const Handle(Geom_Line) aLine;
+  Handle(Geom_Curve) c1 = aLine; // GCC error 
+  Handle(Geom_Curve) c2 (aLine); // ok
+~~~~~
+
+This problem is specific to GCC and it does not appear if macro *OCCT_HANDLE_NOCAST* is used, see @ref upgrade_occt700_cdl_nocast "below".
+
 #### Incorrect use of STANDARD_TYPE and Handle macros
 
 You might need to clean your code from incorrect use of macros *STANDARD_TYPE*() and *Handle*().
@@ -317,7 +329,8 @@ Here is the list of known possible problems at run time after the upgrade to OCC
 #### References to temporary objects
 
 In previous versions, the compiler was able to detect the situation when a local variable of a "reference to a Handle" type is initialized by temporary object, and ensured that lifetime of that object is longer than that of the variable. 
-Since OCCT 7.0, it will not work if types of the temporary object and variable are different (due to involvement of user-defined type cast), thus such temporary object will be destroyed immediately.
+In OCCT 7.0 with default options, it will not work if types of the temporary object and variable are different (due to involvement of user-defined type cast), thus such temporary object will be destroyed immediately.
+This problem does not appear if macro *OCCT_HANDLE_NOCAST* is used during compilation, see below.
 
 Example:
 
@@ -328,6 +341,42 @@ Handle(Geom_TrimmedCurve)::DownCast(aCurve);
 aBC->Transform (T); // access violation in OCCT 7.0
 ~~~~~
 
+@subsubsection upgrade_occt700_cdl_nocast Option to avoid cast of handle to reference to base type
+
+In OCCT 6.x and earlier versions the handle classes formed a hierarchy echoing hierarchy of corresponding object classes.
+This automatically enabled possibility to use handle to derived class in all contexts where handle to base class was needed, e.g. pass it in function by reference without copying:
+
+~~~~
+Standard_Boolean GetCurve (Handle(Geom_Curve)& theCurve);
+....
+Handle(Geom_Line) aLine;
+if (GetCurve (aLine)) {
+  // use aLine, unsafe
+}
+~~~~
+
+This feature was used in multiple places in OCCT and dependent projects.
+However it is potentially unsafe: in the above example no checks are done at compile time or at run time to ensure that argument handle is assigned a type compatible with the type of handle passed as argument. 
+If object of incompatible type (e.g. Geom_Circle) is assigned to *theCurve*, the behavior will be unpredictable.
+
+For compatibility with existing code, by default OCCT 7.0 keeps this possibility, providing operators of type cast to handle to base type.
+Besides being unsafe, in specific situations this feature may cause compile-time or run-time errors as described above.
+
+In order to provide safer behavior, this feature can be disabled by defining a compile-time macro *OCCT_HANDLE_NOCAST*.
+When it is defined, constructors and assignment operators are defined (instead of type cast operators) to convert from handle to defived type to handle to base type.
+This implies creation of temporary objects and hence may be more expensive at run time in some circumstances, however this way is more standard, safer, and in general recommended.
+
+The code that relies on possibility of casting to base should be amended so that handle of argument type is always used in function call, and to use DownCast() to safely convert the result to desired type.
+For instance, the code from the example below can be changed as follows:
+
+~~~~~
+Handle(Geom_Line) aLine;
+Handle(Geom_Curve) aCurve;
+if (GetCurve (aCure) && !(aLine = Handle(Geom_Line)::DownCast (aCurve)).IsNull()) {
+  // use aLine safely
+}
+~~~~~
+
 @subsubsection upgrade_occt700_cdl_compat Preserving compatibility with OCCT 6.x
 
 If you like to preserve the compatibility of your application code with OCCT versions 6.x even after the upgrade to 7.0, consider the following suggestions:
index 28c3c40..68ecf0d 100644 (file)
@@ -1350,12 +1350,12 @@ Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
 
 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const 
 {
-
+  const Handle(SelectMgr_SelectableObject)& aSelObj = anIObj; // to avoid ambiguity
   // Shape was not transfered from AIS_Shape to EntityOwner
   Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
   if( !shape.IsNull() ) 
-    return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(),shape));
-  return myFilters->IsOk(new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj));
+    return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(), aSelObj));
+  return myFilters->IsOk(new SelectMgr_EntityOwner(aSelObj));
 }
 
 
index f4e38ec..e611214 100644 (file)
@@ -46,7 +46,7 @@ const Handle(Standard_Transient)& BinDrivers::Factory(const Standard_GUID& theGU
 #ifdef OCCT_DEBUG
     cout << "BinDrivers : Storage Plugin" << endl;
 #endif
-    static Handle(BinDrivers_DocumentStorageDriver) model_sd =
+    static Handle(Standard_Transient) model_sd =
       new BinDrivers_DocumentStorageDriver;
     return model_sd;
   }
@@ -56,7 +56,7 @@ const Handle(Standard_Transient)& BinDrivers::Factory(const Standard_GUID& theGU
 #ifdef OCCT_DEBUG
     cout << "BinDrivers : Retrieval Plugin" << endl;
 #endif
-    static Handle(BinDrivers_DocumentRetrievalDriver) model_rd =
+    static Handle(Standard_Transient) model_rd =
       new BinDrivers_DocumentRetrievalDriver;
     return model_rd;
   }
index 6b597ac..5ed6d39 100644 (file)
@@ -45,7 +45,7 @@ const Handle(Standard_Transient)& BinLDrivers::Factory(const Standard_GUID& theG
 #ifdef OCCT_DEBUG
     cout << "BinLDrivers : Storage Plugin" << endl;
 #endif
-    static Handle(BinLDrivers_DocumentStorageDriver) model_sd =
+    static Handle(Standard_Transient) model_sd =
       new BinLDrivers_DocumentStorageDriver;
     return model_sd;
   }
@@ -55,7 +55,7 @@ const Handle(Standard_Transient)& BinLDrivers::Factory(const Standard_GUID& theG
 #ifdef OCCT_DEBUG
     cout << "BinLDrivers : Retrieval Plugin" << endl;
 #endif
-    static Handle(BinLDrivers_DocumentRetrievalDriver) model_rd =
+    static Handle(Standard_Transient) model_rd =
       new BinLDrivers_DocumentRetrievalDriver;
     return model_rd;
   }
index 6385c8a..a3181cb 100644 (file)
@@ -37,7 +37,7 @@ const Handle(Standard_Transient)& BinTObjDrivers::Factory(const Standard_GUID& a
 #ifdef OCCT_DEBUG
     cout << "BinTObjDrivers : Storage Plugin" << endl;
 #endif
-    static Handle(BinTObjDrivers_DocumentStorageDriver) model_sd
+    static Handle(Standard_Transient) model_sd
       = new BinTObjDrivers_DocumentStorageDriver;
     return model_sd;
   }
@@ -47,7 +47,7 @@ const Handle(Standard_Transient)& BinTObjDrivers::Factory(const Standard_GUID& a
 #ifdef OCCT_DEBUG
     cout << "BinTObjDrivers : Retrieval Plugin" << endl;
 #endif
-    static Handle (BinTObjDrivers_DocumentRetrievalDriver) model_rd
+    static Handle (Standard_Transient) model_rd
       = new BinTObjDrivers_DocumentRetrievalDriver;
     return model_rd;
   }
index 5edd58b..3d1d36a 100644 (file)
@@ -40,7 +40,7 @@ const Handle(Standard_Transient)& BinXCAFDrivers::Factory(const Standard_GUID& t
 #ifdef OCCT_DEBUG
     cout << "BinXCAFDrivers : Storage Plugin" << endl;
 #endif
-    static Handle(BinXCAFDrivers_DocumentStorageDriver) model_sd =
+    static Handle(Standard_Transient) model_sd =
       new BinXCAFDrivers_DocumentStorageDriver;
     return model_sd;
   }
@@ -50,7 +50,7 @@ const Handle(Standard_Transient)& BinXCAFDrivers::Factory(const Standard_GUID& t
 #ifdef OCCT_DEBUG
     cout << "BinXCAFDrivers : Retrieval Plugin" << endl;
 #endif
-    static Handle(BinXCAFDrivers_DocumentRetrievalDriver) model_rd =
+    static Handle(Standard_Transient) model_rd =
       new BinXCAFDrivers_DocumentRetrievalDriver;
     return model_rd;
   }
index 2180773..c3076bc 100644 (file)
@@ -24,7 +24,7 @@
 PLUGIN(FWOSDriver)
 
 const Handle(Standard_Transient)& FWOSDriver::Factory(const Standard_GUID& /*aGUID*/) {
-  static Handle(FWOSDriver_DriverFactory) f;
+  static Handle(Standard_Transient) f;
   if(f.IsNull()) f = new FWOSDriver_DriverFactory;
   return f;
 }
index 7d4d45a..5aba70b 100644 (file)
@@ -88,7 +88,6 @@ public:
   Standard_EXPORT const Handle(Geom_TrimmedCurve)& Value() const;
 
   operator const Handle(Geom_TrimmedCurve)& () const { return Value(); }
-  operator const Handle(Geom_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom_TrimmedCurve) TheArc;
index 6f1f302..e9e93e7 100644 (file)
@@ -66,7 +66,6 @@ public:
   Standard_EXPORT const Handle(Geom_TrimmedCurve)& Value() const;
 
   operator const Handle(Geom_TrimmedCurve)& () const { return Value(); }
-  operator const Handle(Geom_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom_TrimmedCurve) TheArc;
index 12263ad..0eca295 100644 (file)
@@ -64,7 +64,6 @@ public:
   Standard_EXPORT const Handle(Geom_TrimmedCurve)& Value() const;
 
   operator const Handle(Geom_TrimmedCurve)& () const { return Value(); }
-  operator const Handle(Geom_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom_TrimmedCurve) TheArc;
index 34973ca..b4d0bb5 100644 (file)
@@ -61,7 +61,6 @@ public:
   Standard_EXPORT const Handle(Geom_TrimmedCurve)& Value() const;
 
   operator const Handle(Geom_TrimmedCurve)& () const { return Value(); }
-  operator const Handle(Geom_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom_TrimmedCurve) TheArc;
index 77915cc..7141999 100644 (file)
@@ -101,7 +101,6 @@ public:
   Standard_EXPORT const Handle(Geom_Circle)& Value() const;
 
   operator const Handle(Geom_Circle)& () const { return Value(); }
-  operator const Handle(Geom_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom_Circle) TheCircle;
index 82477d8..db5c35d 100644 (file)
@@ -125,7 +125,6 @@ public:
   Standard_EXPORT const Handle(Geom_ConicalSurface)& Value() const;
 
   operator const Handle(Geom_ConicalSurface)& () const { return Value(); }
-  operator const Handle(Geom_Surface)& () const { return Value(); }
 
 private:
   Handle(Geom_ConicalSurface) TheCone;
index ba0f3d8..a29e75e 100644 (file)
@@ -113,7 +113,6 @@ public:
   Standard_EXPORT const Handle(Geom_CylindricalSurface)& Value() const;
 
   operator const Handle(Geom_CylindricalSurface)& () const { return Value(); }
-  operator const Handle(Geom_Surface)& () const { return Value(); }
 
 private:
   Handle(Geom_CylindricalSurface) TheCylinder;
index 4e201dc..48c5698 100644 (file)
@@ -79,7 +79,6 @@ public:
   Standard_EXPORT const Handle(Geom_Ellipse)& Value() const;
 
   operator const Handle(Geom_Ellipse)& () const { return Value(); }
-  operator const Handle(Geom_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom_Ellipse) TheEllipse;
index 6bdf8bf..7c0f8e2 100644 (file)
@@ -89,7 +89,6 @@ public:
   Standard_EXPORT const Handle(Geom_Hyperbola)& Value() const;
 
   operator const Handle(Geom_Hyperbola)& () const { return Value(); }
-  operator const Handle(Geom_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom_Hyperbola) TheHyperbola;
index 6cdf3a1..44bd5b0 100644 (file)
@@ -78,7 +78,6 @@ public:
   Standard_EXPORT const Handle(Geom_Line)& Value() const;
 
   operator const Handle(Geom_Line)& () const { return Value(); }
-  operator const Handle(Geom_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom_Line) TheLine;
index dfe2339..87644cb 100644 (file)
@@ -102,7 +102,6 @@ public:
   Standard_EXPORT const Handle(Geom_Plane)& Value() const;
 
   operator const Handle(Geom_Plane)& () const { return Value(); }
-  operator const Handle(Geom_Surface)& () const { return Value(); }
 
 private:
   Handle(Geom_Plane) ThePlane;
index 1f92723..82f23ea 100644 (file)
@@ -68,7 +68,6 @@ public:
   Standard_EXPORT const Handle(Geom_TrimmedCurve)& Value() const;
 
   operator const Handle(Geom_TrimmedCurve)& () const { return Value(); }
-  operator const Handle(Geom_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom_TrimmedCurve) TheSegment;
index 6548308..db068b7 100644 (file)
@@ -77,7 +77,6 @@ public:
   Standard_EXPORT const Handle(Geom_RectangularTrimmedSurface)& Value() const;
 
   operator const Handle(Geom_RectangularTrimmedSurface)& () const { return Value(); }
-  operator const Handle(Geom_Surface)& () const { return Value(); }
 
 private:
   Handle(Geom_RectangularTrimmedSurface) TheCone;
index 437aa80..50811ea 100644 (file)
@@ -95,7 +95,6 @@ public:
   Standard_EXPORT const Handle(Geom_RectangularTrimmedSurface)& Value() const;
 
   operator const Handle(Geom_RectangularTrimmedSurface)& () const { return Value(); }
-  operator const Handle(Geom_Surface)& () const { return Value(); }
 
 private:
   Handle(Geom_RectangularTrimmedSurface) TheCyl;
index 34ca3ef..77471e5 100644 (file)
@@ -74,7 +74,6 @@ public:
   Standard_EXPORT const Handle(Geom2d_TrimmedCurve)& Value() const;
 
   operator const Handle(Geom2d_TrimmedCurve)& () const { return Value(); }
-  operator const Handle(Geom2d_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom2d_TrimmedCurve) TheArc;
index a2c8fd2..bf63890 100644 (file)
@@ -66,7 +66,6 @@ public:
   Standard_EXPORT const Handle(Geom2d_TrimmedCurve)& Value() const;
 
   operator const Handle(Geom2d_TrimmedCurve)& () const { return Value(); }
-  operator const Handle(Geom2d_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom2d_TrimmedCurve) TheArc;
index 2393933..155bac5 100644 (file)
@@ -65,7 +65,6 @@ public:
   Standard_EXPORT const Handle(Geom2d_TrimmedCurve)& Value() const;
 
   operator const Handle(Geom2d_TrimmedCurve)& () const { return Value(); }
-  operator const Handle(Geom2d_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom2d_TrimmedCurve) TheArc;
index 854f103..0f0613d 100644 (file)
@@ -65,7 +65,6 @@ public:
   Standard_EXPORT const Handle(Geom2d_TrimmedCurve)& Value() const;
 
   operator const Handle(Geom2d_TrimmedCurve)& () const { return Value(); }
-  operator const Handle(Geom2d_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom2d_TrimmedCurve) TheArc;
index d51dcaa..ce07328 100644 (file)
@@ -103,7 +103,6 @@ public:
   Standard_EXPORT const Handle(Geom2d_Circle)& Value() const;
 
   operator const Handle(Geom2d_Circle)& () const { return Value(); }
-  operator const Handle(Geom2d_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom2d_Circle) TheCircle;
index 849100f..350bb0b 100644 (file)
@@ -88,7 +88,6 @@ public:
   Standard_EXPORT const Handle(Geom2d_Ellipse)& Value() const;
 
   operator const Handle(Geom2d_Ellipse)& () const { return Value(); }
-  operator const Handle(Geom2d_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom2d_Ellipse) TheEllipse;
index e9936c8..74485c7 100644 (file)
@@ -108,7 +108,6 @@ public:
   Standard_EXPORT const Handle(Geom2d_Hyperbola)& Value() const;
 
   operator const Handle(Geom2d_Hyperbola)& () const { return Value(); }
-  operator const Handle(Geom2d_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom2d_Hyperbola) TheHyperbola;
index a13d9d6..68c8890 100644 (file)
@@ -77,7 +77,6 @@ public:
   Standard_EXPORT const Handle(Geom2d_Line)& Value() const;
 
   operator const Handle(Geom2d_Line)& () const { return Value(); }
-  operator const Handle(Geom2d_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom2d_Line) TheLine;
index 0111c22..0687d7d 100644 (file)
@@ -106,7 +106,6 @@ public:
   Standard_EXPORT const Handle(Geom2d_Parabola)& Value() const;
 
   operator const Handle(Geom2d_Parabola)& () const { return Value(); }
-  operator const Handle(Geom2d_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom2d_Parabola) TheParabola;
index 679bc14..e249819 100644 (file)
@@ -82,7 +82,6 @@ public:
   Standard_EXPORT const Handle(Geom2d_TrimmedCurve)& Value() const;
 
   operator const Handle(Geom2d_TrimmedCurve)& () const { return Value(); }
-  operator const Handle(Geom2d_Curve)& () const { return Value(); }
 
 private:
   Handle(Geom2d_TrimmedCurve) TheSegment;
index 3762d4b..ab026e9 100644 (file)
@@ -210,7 +210,7 @@ OpenGl_Context::~OpenGl_Context()
   }
 
   // release shared resources if any
-  if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
+  if (mySharedResources->GetRefCount() <= 1)
   {
     myShaderManager.Nullify();
     for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
@@ -2384,7 +2384,7 @@ void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
   {
     return;
   }
-  const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
+  auto& aRes = mySharedResources->Find (theKey);
   if (aRes->GetRefCount() > 1)
   {
     return;
@@ -2432,7 +2432,7 @@ void OpenGl_Context::ReleaseDelayed()
       continue;
     }
 
-    Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
+    auto& aRes = mySharedResources->ChangeFind (aKey);
     if (aRes->GetRefCount() > 1)
     {
       // should be only 1 instance in mySharedResources
index 22ee0e2..75f46a5 100644 (file)
@@ -40,7 +40,7 @@ namespace
     State_Visible
   };
 
-  static BeforeHighlightState StructureState(const Handle(PrsMgr_Prs)& theStructure)
+  static BeforeHighlightState StructureState(const Handle(Prs3d_Presentation)& theStructure)
   {
     return !theStructure->IsDisplayed() ?
       State_Empty : !theStructure->IsVisible() ?
index e93f122..fd2879d 100644 (file)
@@ -133,7 +133,7 @@ private:
   Standard_EXPORT static Handle(Prs3d_Projector) Projector (const Handle(Graphic3d_DataStructureManager)& theProjector);
 
   Handle(PrsMgr_PresentationManager) myPresentationManager;
-  Handle(PrsMgr_Prs) myStructure;
+  Handle(Prs3d_Presentation) myStructure;
   PrsMgr_PresentableObjectPointer myPresentableObject;
   Standard_Boolean myMustBeUpdated;
   Standard_Integer myBeforeHighlightState;
index c037e60..23b075b 100644 (file)
@@ -24,13 +24,27 @@ class Standard_Transient;
 
 namespace opencascade {
 
+  //! Trait yielding true if class T1 is base of T2 but not the same
+  template <class T1, class T2, class Dummy = void>
+  struct is_base_but_not_same : std::is_base_of <T1, T2> {};
+
+  //! Explicit specialization of is_base_of trait to workaround the
+  //! requirement of type to be complete when T1 and T2 are the same.
+  template <class T1, class T2>
+  struct is_base_but_not_same <T1, T2, typename std::enable_if <std::is_same <T1, T2>::value>::type> : std::false_type {};
+
   //! 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.
+  //! in functions accepting reference to handle to base class.
+  //!
+  //! These casts (potentially unsafe) can be disabled by defining macro
+  //! OCCT_HANDLE_NOCAST; if it is defined, generalized copy constructor
+  //! and assignment operators are defined allowing to initialize handle
+  //! of base type from handle to derived type.
   template <class T>
   class handle
   {
@@ -48,14 +62,7 @@ namespace opencascade {
     {
       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)
     {
@@ -96,14 +103,7 @@ namespace opencascade {
       Assign (const_cast<T*>(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<const T*>(this->entity); }
 
@@ -202,13 +202,36 @@ namespace opencascade {
 
 #endif
 
-    //! Upcast to const reference to base type.
+    // Support of conversions to handle of base type:
+    // - copy and move constructors and assignment operators if OCCT_HANDLE_NOCAST is defined
+    // - operators of upcast to const reference to base type otherwise
 #if (defined(__clang__)) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1206) || \
     (defined(_MSC_VER) && _MSC_VER >= 1800) || \
     (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
 
+#ifdef OCCT_HANDLE_NOCAST
+
+    //! Generalized copy constructor.
+    //! Constructs handle holding entity of base type (T) from the one which holds entity of derived type (T2).
+    template <class T2, typename = typename std::enable_if <is_base_but_not_same <T, T2>::value>::type>
+    handle (const handle<T2>& theHandle) :
+      entity(theHandle.entity)
+    {
+      BeginScope();
+    }
+
+    //! Generalized assignment operator
+    template <class T2, typename = typename std::enable_if <is_base_but_not_same <T, T2>::value>::type>
+    handle operator = (const handle<T2>& theHandle)
+    {
+      Assign (theHandle.entity);
+      return *this;
+    }
+
+#else
+
     //! Upcast to const reference to base type.
-    template <class T2, typename = typename std::enable_if<std::is_base_of<T2, T>::value>::type>
+    template <class T2, typename = typename std::enable_if<is_base_but_not_same<T2, T>::value>::type>
     operator const handle<T2>& () const
     {
       return reinterpret_cast<const handle<T2>&>(*this);
@@ -216,14 +239,39 @@ namespace opencascade {
 
     //! Upcast to non-const reference to base type.
     //! NB: this cast can be dangerous, but required for legacy code; see #26377
-    template <class T2, typename = typename std::enable_if<std::is_base_of<T2, T>::value>::type>
+    template <class T2, typename = typename std::enable_if<is_base_but_not_same<T2, T>::value>::type>
     operator handle<T2>& ()
     {
       return reinterpret_cast<handle<T2>&>(*this);
     }
 
+#endif /* OCCT_HANDLE_NOCAST */
+
 #else /* fallback version for compilers not supporting default arguments of function templates (VC10, VC11, GCC below 4.3) */
 
+#ifdef OCCT_HANDLE_NOCAST
+
+    //! Generalized copy constructor.
+    //! Constructs handle holding entity of base type (T) from the one which holds entity of derived type (T2).
+    template <class T2>
+    handle (const handle<T2>& theHandle, typename std::enable_if <is_base_but_not_same <T, T2>::value>::type* = nullptr) :
+      entity(theHandle.entity)
+    {
+      BeginScope();
+    }
+
+    //! Generalized assignment operator.
+    template <class T2>
+    handle operator = (const handle<T2>& theHandle)
+    {
+      std::enable_if <is_base_but_not_same <T, T2>::value, void*>::type aTypeCheckHelperVar;
+      (void)aTypeCheckHelperVar;
+      Assign (theHandle.entity);
+      return *this;
+    }
+
+#else
+
     //! 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 
@@ -233,7 +281,7 @@ namespace opencascade {
     {
       // 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<typename std::enable_if<std::is_base_of<T2, T>::value, const handle<T2>&>::type>(*this);
+      return reinterpret_cast<typename std::enable_if<is_base_but_not_same<T2, T>::value, const handle<T2>&>::type>(*this);
     }
 
     //! Upcast to non-const reference to base type.
@@ -244,10 +292,12 @@ namespace opencascade {
     {
       // 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<typename std::enable_if<std::is_base_of<T2, T>::value, handle<T2>&>::type>(*this);
+      return reinterpret_cast<typename std::enable_if<is_base_but_not_same<T2, T>::value, handle<T2>&>::type>(*this);
     }
 
-#endif
+#endif /* OCCT_HANDLE_NOCAST */
+
+#endif /* compiler switch */
 
   private:
 
index b6cec72..29ce223 100644 (file)
@@ -68,7 +68,7 @@ void TopOpeBRepBuild_LoopSet::NextLoop()
 //purpose  : 
 //=======================================================================
 
-const Handle(TopOpeBRepBuild_Loop)& TopOpeBRepBuild_LoopSet::Loop() const
+Handle(TopOpeBRepBuild_Loop) TopOpeBRepBuild_LoopSet::Loop() const
 {
   const Handle(TopOpeBRepBuild_Loop)& L = myLoopIterator.Value();
   return L;
index c2c9333..527a406 100644 (file)
@@ -48,7 +48,7 @@ public:
   
   Standard_EXPORT virtual void NextLoop();
   
-  Standard_EXPORT virtual const Handle(TopOpeBRepBuild_Loop)& Loop() const;
+  Standard_EXPORT virtual Handle(TopOpeBRepBuild_Loop) Loop() const;
 
 
 
index 028026b..91e8559 100644 (file)
@@ -337,10 +337,9 @@ void  TopOpeBRepBuild_PaveSet::NextLoop()
 //purpose  : 
 //=======================================================================
 
-const Handle(TopOpeBRepBuild_Loop)& TopOpeBRepBuild_PaveSet::Loop()const 
+Handle(TopOpeBRepBuild_Loop) TopOpeBRepBuild_PaveSet::Loop()const 
 {
-  const Handle(TopOpeBRepBuild_Loop)& L = myVerticesIt.Value();
-  return L;
+  return Handle(TopOpeBRepBuild_Loop)(myVerticesIt.Value());
 }
 
 
index 18149b7..8915cd1 100644 (file)
@@ -57,7 +57,7 @@ public:
   
   Standard_EXPORT virtual void NextLoop() Standard_OVERRIDE;
   
-  Standard_EXPORT virtual const Handle(TopOpeBRepBuild_Loop)& Loop() const Standard_OVERRIDE;
+  Standard_EXPORT virtual Handle(TopOpeBRepBuild_Loop) Loop() const Standard_OVERRIDE;
   
   Standard_EXPORT const TopoDS_Edge& Edge() const;
   
index 3df9402..cc9e0b5 100644 (file)
@@ -659,7 +659,7 @@ static IFSelect_ReturnStatus TransferFinder
   dispfiles->SetFinalSelection(slr);
   WS->AddNamedItem ("xst-disp-files",dispfiles);
   Handle(IFSelect_DispPerSignature) dispsign = new IFSelect_DispPerSignature;
-  dispsign->SetSignCounter(new IFSelect_SignCounter(stc));
+  dispsign->SetSignCounter(new IFSelect_SignCounter(Handle(IFSelect_Signature)(stc)));
   dispsign->SetFinalSelection(slr);
   WS->AddNamedItem ("xst-disp-sign",dispsign);
 
index 34d858d..4543605 100644 (file)
@@ -45,7 +45,7 @@ const Handle(Standard_Transient)& XmlDrivers::Factory(const Standard_GUID& theGU
 #ifdef OCCT_DEBUG
     cout << "XmlDrivers : Storage Plugin" << endl;
 #endif
-    static Handle(XmlDrivers_DocumentStorageDriver) model_sd =
+    static Handle(Standard_Transient) model_sd =
       new XmlDrivers_DocumentStorageDriver
         ("Copyright: Open Cascade, 2001-2002"); // default copyright
     return model_sd;
@@ -56,7 +56,7 @@ const Handle(Standard_Transient)& XmlDrivers::Factory(const Standard_GUID& theGU
 #ifdef OCCT_DEBUG
     cout << "XmlDrivers : Retrieval Plugin" << endl;
 #endif
-    static Handle (XmlDrivers_DocumentRetrievalDriver) model_rd =
+    static Handle (Standard_Transient) model_rd =
       new XmlDrivers_DocumentRetrievalDriver ();
     return model_rd;
   }
index 4f365b8..dac1ecb 100644 (file)
@@ -45,7 +45,7 @@ const Handle(Standard_Transient)& XmlLDrivers::Factory(const Standard_GUID& theG
 #ifdef OCCT_DEBUG
     cout << "XmlLDrivers : Storage Plugin" << endl;
 #endif
-    static Handle(XmlLDrivers_DocumentStorageDriver) model_sd =
+    static Handle(Standard_Transient) model_sd =
       new XmlLDrivers_DocumentStorageDriver
         ("Copyright: Open Cascade, 2001-2002"); // default copyright
     return model_sd;
@@ -56,7 +56,7 @@ const Handle(Standard_Transient)& XmlLDrivers::Factory(const Standard_GUID& theG
 #ifdef OCCT_DEBUG
     cout << "XmlLDrivers : Retrieval Plugin" << endl;
 #endif
-    static Handle (XmlLDrivers_DocumentRetrievalDriver) model_rd =
+    static Handle (Standard_Transient) model_rd =
       new XmlLDrivers_DocumentRetrievalDriver ();
     return model_rd;
   }
index 443f1f4..e3a42b3 100644 (file)
@@ -38,7 +38,7 @@ const Handle(Standard_Transient)& XmlTObjDrivers::Factory(const Standard_GUID& a
 #ifdef OCCT_DEBUG
     cout << "XmlTObjDrivers : Storage Plugin" << endl;
 #endif
-    static Handle(XmlTObjDrivers_DocumentStorageDriver) model_sd
+    static Handle(Standard_Transient) model_sd
       = new XmlTObjDrivers_DocumentStorageDriver
         ("Copyright: Open CASCADE 2004"); // default copyright
     return model_sd;
@@ -49,7 +49,7 @@ const Handle(Standard_Transient)& XmlTObjDrivers::Factory(const Standard_GUID& a
 #ifdef OCCT_DEBUG
     cout << "XmlTObjDrivers : Retrieval Plugin" << endl;
 #endif
-    static Handle (XmlTObjDrivers_DocumentRetrievalDriver) model_rd
+    static Handle (Standard_Transient) model_rd
       = new XmlTObjDrivers_DocumentRetrievalDriver;
     return model_rd;
   }
index 719bdca..7cc199c 100644 (file)
@@ -33,7 +33,7 @@ const Handle(Standard_Transient)& XmlXCAFDrivers::Factory(const Standard_GUID& a
 #ifdef OCCT_DEBUG
     cout << "XmlXCAFDrivers : Storage Plugin" << endl;
 #endif
-    static Handle(XmlXCAFDrivers_DocumentStorageDriver) model_sd 
+    static Handle(Standard_Transient) model_sd 
       = new XmlXCAFDrivers_DocumentStorageDriver
         ("Copyright: Open Cascade, 2001-2002"); // default copyright
     return model_sd;
@@ -43,7 +43,7 @@ const Handle(Standard_Transient)& XmlXCAFDrivers::Factory(const Standard_GUID& a
 #ifdef OCCT_DEBUG
     cout << "XmlXCAFDrivers : Retrieval Plugin" << endl;
 #endif
-    static Handle (XmlXCAFDrivers_DocumentRetrievalDriver) model_rd 
+    static Handle (Standard_Transient) model_rd 
       = new XmlXCAFDrivers_DocumentRetrievalDriver;
     return model_rd;
   }