0023569: Adding NCollection_StdAllocator
authorRoman Lygin <roman.lygin@gmail.com>
Fri, 30 Nov 2012 12:06:46 +0000 (16:06 +0400)
committerRoman Lygin <roman.lygin@gmail.com>
Fri, 30 Nov 2012 12:06:46 +0000 (16:06 +0400)
Adding NCollection_StdAllocator
Adding NCollection_StdAllocator (correcting previous commit)
- addressed code review comment by kgv with using 2 (vs 4) spaces and amending max_size()

Add new draw-commands
Adding test case for this bug

src/NCollection/FILES
src/NCollection/NCollection_StdAllocator.hxx [new file with mode: 0644]
src/QANCollection/FILES
src/QANCollection/QANCollection.cdl
src/QANCollection/QANCollection.cxx
src/QANCollection/QANCollection4.cxx [new file with mode: 0755]
tests/bugs/fclasses/bug23569_1 [new file with mode: 0755]
tests/bugs/fclasses/bug23569_2 [new file with mode: 0755]

index ea23893..b5da38b 100755 (executable)
@@ -6,6 +6,8 @@ NCollection_IncAllocator.hxx
 NCollection_IncAllocator.cxx
 NCollection_HeapAllocator.hxx
 NCollection_HeapAllocator.cxx
+NCollection_StdAllocator.hxx
+
 NCollection_ListNode.hxx
 NCollection_BaseList.hxx
 NCollection_BaseList.cxx
diff --git a/src/NCollection/NCollection_StdAllocator.hxx b/src/NCollection/NCollection_StdAllocator.hxx
new file mode 100644 (file)
index 0000000..5a4edb6
--- /dev/null
@@ -0,0 +1,174 @@
+// Author: Roman Lygin, 2012.
+// This file is put into Public Domain and thus can freely be used for any purpose.
+// The author disclaims any rights and liabilities.
+
+#ifndef _NCollection_StdAllocator_HeaderFile
+#define _NCollection_StdAllocator_HeaderFile
+
+#include <NCollection_BaseAllocator.hxx>
+
+#if _MSC_VER
+  //Workaround for false "unreferenced parameter" warning in destroy().
+  #pragma warning (push)
+  #pragma warning (disable: 4100)
+#endif
+
+//! Implements allocator requirements as defined in ISO C++ Standard 2003, section 20.1.5.
+/*! The allocator uses instance of the NCollection_BaseAllocator (sub)class for memory
+  allocation/deallocation. The allocator can be used with standard
+  containers (std::vector, std::map, etc) to take advantage of NCollection_IncAllocator
+  which implements memory region concept, and hence to increase performance in specific
+  cases.
+
+  The underlying NCollection_BaseAllocator instance can be received using the Allocator()
+  method.
+
+  Example of use:
+  \code
+  Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator();
+  NCollection_StdAllocator<TopoDS_Shape> aSAlloc (anIncAlloc);
+  std::list<TopoDS_Shape, NCollection_StdAllocator<TopoDS_Shape> > aL (aSAlloc);
+  TopoDS_Solid aSolid = BRepPrimAPI_MakeBox (10., 20., 30.);
+  aL.push_back (aSolid);
+  \endcode
+*/
+template<typename T>
+class NCollection_StdAllocator {
+public:
+  typedef T value_type;
+  typedef value_type* pointer;
+  typedef const value_type* const_pointer;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  template<typename U> struct rebind {
+    typedef NCollection_StdAllocator<U> other;
+  };
+
+  //! Constructor.
+  /*! Creates an object using default Open CASCADE allocation mechanism, i.e. which uses
+    Standard::Allocate() and Standard::Free() underneath.
+  */
+  NCollection_StdAllocator() throw()
+  { myAlloc = NCollection_BaseAllocator::CommonBaseAllocator(); }
+
+  //! Constructor.
+  /*! Saves \a theAlloc as an underlying allocator instance.*/
+  NCollection_StdAllocator( const Handle(NCollection_BaseAllocator)& theAlloc) throw()
+  { myAlloc = theAlloc; }
+
+  //! Constructor.
+  /*! Copies Allocator() from \a X.*/
+  NCollection_StdAllocator( const NCollection_StdAllocator& X) throw() { myAlloc = X.myAlloc; }
+
+  //! Destructor.
+  /*! Empty implementation.*/
+  ~NCollection_StdAllocator() throw() {}
+
+  //! Constructor.
+  /*! Copies Allocator() from \a Y.*/
+  template<typename U> NCollection_StdAllocator( const NCollection_StdAllocator<U>& Y) throw()
+  { myAlloc = Y.Allocator(); }
+
+  //! Returns an object address.
+  /*! Returns &x.*/
+  pointer address( reference x ) const { return &x; }
+
+  //! Returns an object address.
+  /*! Returns &x.*/
+  const_pointer address( const_reference x ) const { return &x; }
+  
+  //! Allocates memory for \a n objects.
+  /*! Uses underlying allocator to allocate memory.*/
+  pointer allocate( size_type n, const void* /*hint*/ = 0 )
+  { return pointer( myAlloc->Allocate( n * sizeof( value_type ))); }
+
+  //! Frees previously allocated memory.
+  /*! Uses underlying allocator to deallocate memory.*/
+  void deallocate( pointer p, size_type ) { myAlloc->Free( p ); }
+
+  //! Returns the largest value for which method allocate might succeed.
+  size_type max_size() const throw()
+  {
+    size_type aMax = static_cast<size_type>( -1 ) / sizeof( value_type );
+    return aMax;
+  }
+
+  //! Constructs an object.
+  /*! Uses placement new operator and copy constructor to construct an object.*/
+  void construct( pointer p, const_reference val )
+  { new( static_cast<void*>( p )) value_type( val ); }
+
+  //! Destroys the object.
+  /*! Uses object destructor.*/
+  void destroy( pointer p ) { p->~value_type(); }
+
+  //! Returns an underlying NCollection_BaseAllocator instance.
+  /*! Returns an object specified in the constructor.*/
+  const Handle(NCollection_BaseAllocator)& Allocator() const { return myAlloc; }
+
+protected:
+  Handle(NCollection_BaseAllocator) myAlloc;
+};
+
+#if _MSC_VER
+  #pragma warning (pop)
+#endif
+
+
+//! Implements specialization NCollection_StdAllocator<void>.
+/*! Specialization is of low value and should normally be avoided in favor of a typed specialization.
+
+  Example of use:
+  \code
+  Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator();
+  NCollection_StdAllocator<void> aVAlloc (anIncAlloc);
+  std::vector<double, NCollection_StdAllocator<double> > aV3 (aVAlloc);
+  aV3.push_back (10.);
+  \endcode
+*/
+template<> 
+class NCollection_StdAllocator<void> {
+public:
+  typedef void* pointer;
+  typedef const void* const_pointer;
+  typedef void value_type;
+  template<typename U> struct rebind {
+    typedef NCollection_StdAllocator<U> other;
+  };
+
+  //! Constructor.
+  /*! Creates an object using default Open CASCADE allocation mechanism, i.e. which uses
+    Standard::Allocate() and Standard::Free() underneath.
+  */
+  NCollection_StdAllocator() throw()
+  { myAlloc = NCollection_BaseAllocator::CommonBaseAllocator(); }
+
+  //! Constructor.
+  /*! Saves \a theAlloc as an underlying allocator instance.*/
+  NCollection_StdAllocator( const Handle(NCollection_BaseAllocator)& theAlloc) throw()
+  { myAlloc = theAlloc; }
+
+  //! Constructor.
+  /*! Copies Allocator() from \a X.*/
+  NCollection_StdAllocator( const NCollection_StdAllocator& X) throw() { myAlloc = X.myAlloc; }
+
+  //! Returns an underlying NCollection_BaseAllocator instance.
+  /*! Returns an object specified in the constructor.*/
+  const Handle(NCollection_BaseAllocator)& Allocator() const { return myAlloc; }
+
+protected:
+  Handle(NCollection_BaseAllocator) myAlloc;
+};
+
+template<typename T, typename U>
+inline bool operator==( const NCollection_StdAllocator<T>& X, const NCollection_StdAllocator<U>& Y)
+{ return !!(X.Allocator() == Y.Allocator()); }
+
+template<typename T, typename U>
+inline bool operator!=( const NCollection_StdAllocator<T>& X, const NCollection_StdAllocator<U>& Y)
+{ return !(X == Y); }
+
+
+#endif
index 590efdf..0e7de08 100755 (executable)
@@ -4,6 +4,7 @@ QANCollection.cxx
 QANCollection1.cxx
 QANCollection2.cxx
 QANCollection3.cxx
+QANCollection4.cxx
 QANCollection_Common.cxx
 QANCollection_Common.hxx
 QANCollection_Common2.hxx
@@ -17,4 +18,4 @@ QANCollection_PerfLists.hxx
 QANCollection_PerfMaps.hxx
 QANCollection_PerfTest.hxx
 QANCollectionTest.cxx
-QANCollection_PerfSparseArray.hxx
\ No newline at end of file
+QANCollection_PerfSparseArray.hxx
index 0d1b63f..c6d54cf 100755 (executable)
@@ -58,5 +58,6 @@ is
     Commands1(DI : in out Interpretor from Draw);
     Commands2(DI : in out Interpretor from Draw);
     Commands3(DI : in out Interpretor from Draw);
+    Commands4(DI : in out Interpretor from Draw);
 
 end;
index 1d5ccc4..303d48c 100755 (executable)
@@ -29,5 +29,6 @@ void QANCollection::Commands(Draw_Interpretor& theCommands) {
   QANCollection::Commands1(theCommands);
   QANCollection::Commands2(theCommands);
   QANCollection::Commands3(theCommands);
+  QANCollection::Commands4(theCommands);
   return;
 }
diff --git a/src/QANCollection/QANCollection4.cxx b/src/QANCollection/QANCollection4.cxx
new file mode 100755 (executable)
index 0000000..48b27a5
--- /dev/null
@@ -0,0 +1,154 @@
+// Created on: 2004-03-05
+// Created by: Mikhail KUZMITCHEV
+// Copyright (c) 2004-2012 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+
+
+#include <QANCollection.hxx>
+#include <Draw_Interpretor.hxx>
+
+#include <NCollection_StdAllocator.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <list>
+#include <vector>
+
+//=======================================================================
+//function : QANColStdAllocator1
+//purpose  : 
+//=======================================================================
+static Standard_Integer QANColStdAllocator1(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
+{
+  if ( argc != 1) {
+    di << "Usage : " << argv[0] << "\n";
+    return 1;
+  }
+
+  //type definitions
+  typedef Handle_Standard_Transient elem_type;
+  typedef NCollection_StdAllocator<elem_type> allocator_type;
+  if ( sizeof (allocator_type::value_type) == sizeof (elem_type) ) {
+    di << "value_type : OK\n";
+  } else {
+    di << "value_type : Error\n";
+  }
+  if ( sizeof (allocator_type::pointer) == sizeof (void*) ) {
+    di << "pointer : OK\n";
+  } else {
+    di << "pointer : Error\n";
+  }
+  if (sizeof (allocator_type::const_pointer)  == sizeof (void*) ) {
+    di << "const_pointer : OK\n";
+  } else {
+    di << "const_pointer : Error\n";
+  }
+
+  elem_type aDummy;
+  allocator_type::reference aRef = aDummy;
+  allocator_type::const_reference aConstRef = aDummy;
+  if ( sizeof (allocator_type::size_type) == sizeof (size_t) ) {
+    di << "size_type : OK\n";
+  } else {
+    di << "size_type : Error\n";
+  }
+  if ( sizeof (allocator_type::difference_type) == sizeof (ptrdiff_t) ) {
+    di << "allocator_type : OK\n";
+  } else {
+    di << "allocator_type : Error\n";
+  }
+
+  typedef int other_elem_type;
+  if ( sizeof (allocator_type::rebind<other_elem_type>::other::value_type) == sizeof (other_elem_type) ) {
+    di << "other_elem_type : OK\n";
+  } else {
+    di << "other_elem_type : Error\n";
+  }
+
+  return 0;
+}
+
+//=======================================================================
+//function : QANColStdAllocator2
+//purpose  : 
+//=======================================================================
+static Standard_Integer QANColStdAllocator2(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
+{
+  if ( argc != 1) {
+    di << "Usage : " << argv[0] << "\n";
+    return 1;
+  }
+
+  //create incremental allocator outside the scope of objects it will manage
+  Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator();
+
+  {
+    //typed allocator
+    NCollection_StdAllocator<int> aSAlloc (anIncAlloc);
+    std::list<int, NCollection_StdAllocator<int> > aL (aSAlloc);
+    aL.push_back (2);
+    if ( aL.size() == size_t (1) ) {
+      di << "Test1 : OK\n";
+    } else {
+      di << "Test1 : Error\n";
+    }
+
+    //type cast
+    NCollection_StdAllocator<char> aCAlloc;
+    std::vector<int, NCollection_StdAllocator<int> > aV (aCAlloc);
+    aV.push_back (1);
+    if ( aV.size() == size_t (1) ) {
+      di << "Test2 : OK\n";
+    } else {
+      di << "Test2 : Error\n";
+    }
+
+    //using void-specialization allocator
+    std::vector<int, NCollection_StdAllocator<void> > aV2;
+    aV2.resize (10);
+    aV2.push_back (-1);
+    if ( aV2.size() == size_t (11) ) {
+      di << "Test3 : OK\n";
+    } else {
+      di << "Test3 : Error\n";
+    }
+
+    //equality of allocators
+    if ( aSAlloc != aCAlloc ) {
+      di << "Test4 : OK\n";
+    } else {
+      di << "Test4 : Error\n";
+    }
+    NCollection_StdAllocator<int> anIAlloc (anIncAlloc);
+    if ( aSAlloc == anIAlloc ) {
+      di << "Test5 : OK\n";
+    } else {
+      di << "Test5 : Error\n";
+    }
+
+  }
+
+  return 0;
+}
+
+void QANCollection::Commands4(Draw_Interpretor& theCommands) {
+  const char *group = "QANCollection";
+
+  theCommands.Add("QANColStdAllocator1", "QANColStdAllocator1", __FILE__, QANColStdAllocator1, group);  
+  theCommands.Add("QANColStdAllocator2", "QANColStdAllocator2", __FILE__, QANColStdAllocator2, group);  
+
+  return;
+}
diff --git a/tests/bugs/fclasses/bug23569_1 b/tests/bugs/fclasses/bug23569_1
new file mode 100755 (executable)
index 0000000..56a530f
--- /dev/null
@@ -0,0 +1,9 @@
+puts "======="
+puts "OCC23569"
+puts "======="
+puts ""
+###########################################################################
+## Adding NCollection_StdAllocator
+###########################################################################
+
+QANColStdAllocator1
diff --git a/tests/bugs/fclasses/bug23569_2 b/tests/bugs/fclasses/bug23569_2
new file mode 100755 (executable)
index 0000000..2ab7ec4
--- /dev/null
@@ -0,0 +1,9 @@
+puts "======="
+puts "OCC23569"
+puts "======="
+puts ""
+###########################################################################
+## Adding NCollection_StdAllocator
+###########################################################################
+
+QANColStdAllocator2