Commit before breaking everything
[matches/honours.git] / research / transmission_spectroscopy / TOF / Win32++ / include / shared_ptr.h
diff --git a/research/transmission_spectroscopy/TOF/Win32++/include/shared_ptr.h b/research/transmission_spectroscopy/TOF/Win32++/include/shared_ptr.h
new file mode 100644 (file)
index 0000000..2c85e52
--- /dev/null
@@ -0,0 +1,199 @@
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF\r
+// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\r
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
+// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\r
+// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\r
+// OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+// This software was developed from code available in the public domain\r
+// and has no copyright.\r
+\r
+\r
+// About Shared_Ptr:\r
+// Shared_Ptr wraps a reference-counted smart pointer around a dynamically\r
+// allocated object. Unlike auto_ptr, the Shared_Ptr can be used as a smart\r
+// pointer for objects stored in containers like std::vector. Do not use\r
+// Shared_Ptr (or shared_ptr or auto_ptr) for dynamically allocated arrays.\r
+// See below for advice on how to wrap dynamically allocated arrays in a\r
+// vector.\r
+//\r
+// The next standard of C++ will also contain a shared_ptr. Some modern\r
+// compilers already have a shared_ptr available as std::tr1::shared_ptr. If\r
+// your compiler already provides a shared_ptr, or if you have Boost, you\r
+// should use that smart pointer instead. This class has been provided for\r
+// those users who don't have easy access to an "official" shared_ptr.\r
+// Note that this class is "Shared_Ptr", a slightly different name to the\r
+// future "shared_ptr" to avoid naming conflicts.\r
+\r
+// Advantages of Shared_Ptr (or shared_ptr where available):\r
+//  - Shared_Ptr can be safely copied. This makes then suitable for containers.\r
+//  - Shared_Ptr automatically calls delete for the wrapped pointer when\r
+//     its last copy goes out of scope.\r
+//  - Shared_Ptr simplifies exception safety.\r
+//\r
+// Without smart pointers, it can be quite challenging to ensure that every\r
+// dynamically allocated pointer (i.e. use of new) is deleted in the event of\r
+// all possible exceptions. In addition to the exceptions we throw ourselves,\r
+// "new" itself will throw an exception it it fails, as does the STL (Standard\r
+// Template Library which includes vector and string). Without smart pointers\r
+// we often need to resort to additional try/catch blocks simply to avoid\r
+// memory leaks when exceptions occur.\r
+\r
+// Examples:\r
+//  Shared_Ptr<CWnd> w1(new CWnd);\r
+//   or\r
+//  Shared_Ptr<CWnd> w1 = new CWnd;\r
+//   or\r
+//  typedef Shared_Ptr<CWnd> CWndPtr;\r
+//  CWndPtr w1 = new CWnd;\r
+//   or\r
+//  typedef Shared_Ptr<CWnd> CWndPtr;\r
+//  CWndPtr w1(new CWnd);\r
+//\r
+//  And with a vector\r
+//  typedef Shared_Ptr<CWnd> CWndPtr;\r
+//  std::vector<CWndPtr> MyVector;\r
+//  MyVector.push_back(new CWnd);\r
+//   or\r
+//  typedef Shared_Ptr<CWnd> CWndPtr;\r
+//  CWnd* pWnd = new CWnd;\r
+//  std::vector<CWndPtr> MyVector;\r
+//  MyVector.push_back(pWnd);\r
+//\r
+\r
+// How to handle dynamically allocated arrays:\r
+// While we could create a smart pointer for arrays, we don't need to because\r
+// std::vector already handles this for us. Consider the following example:\r
+//    int nLength = ::GetWindowTextLength(m_hWnd);\r
+//       pTChar = new TCHAR[nLength+1];\r
+//       memset(pTChar, 0, (nLength+1)*sizeof(TCHAR));\r
+//       ::GetWindowText(m_hWnd, m_pTChar, nLength+1);\r
+//    ....\r
+//    delete[] pTChar;\r
+//\r
+// This can be improved by using a vector instead of an array\r
+//    int nLength = ::GetWindowTextLength(m_hWnd);\r
+//    std::vector<TCHAR> vTChar( nLength+1, _T('\0') );\r
+//    TCHAR* pTCharArray = &vTChar.front();\r
+//    ::GetWindowText(m_hWnd, pTCharArray, nLength+1);\r
+//\r
+// This works because the memory in a vector is always contiguous. Note that\r
+// this is NOT always true of std::string.\r
+\r
+\r
+// Summing up:\r
+// In my opinion, "naked" pointers for dynamically created objects should be \r
+// avoided in modern C++ code. That's to say that calls to "new" should be \r
+// wrapped in some sort of smart pointer wherever possible. This eliminates \r
+// the possibility of memory leaks (particularly in the event of exceptions). \r
+// It also elminiates the need for delete in user's code.\r
+\r
+#ifndef _WIN32XX_SHARED_PTR_\r
+#define _WIN32XX_SHARED_PTR_\r
+\r
+namespace Win32xx\r
+{\r
+\r
+       template <class T1>\r
+       class Shared_Ptr\r
+       {\r
+       public:\r
+               Shared_Ptr() : m_ptr(NULL), m_count(NULL) { }\r
+               Shared_Ptr(T1 * p) : m_ptr(p), m_count(NULL)\r
+               {\r
+                       try\r
+                       {\r
+                               if (m_ptr) m_count = new long(0);\r
+                inc_ref();\r
+                       }\r
+                       // catch the unlikely event of 'new long(0)' throwing an exception\r
+                       catch (const std::bad_alloc&)\r
+                       {\r
+                               delete m_ptr;\r
+                               throw;\r
+                       }\r
+               }\r
+               Shared_Ptr(const Shared_Ptr& rhs) : m_ptr(rhs.m_ptr), m_count(rhs.m_count) { inc_ref(); }\r
+               ~Shared_Ptr()\r
+               {\r
+                       if(m_count && 0 == dec_ref())\r
+                       {\r
+                               // Note: This code doesn't handle a pointer to an array.\r
+                               //  We would need delete[] m_ptr to handle that.\r
+                               delete m_ptr;\r
+                               delete m_count;\r
+                       }\r
+               }\r
+\r
+               T1* get() const { return m_ptr; }\r
+               long use_count() const { return m_count? *m_count : 0; }\r
+               bool unique() const { return (m_count && (*m_count == 1)); }\r
+\r
+               void swap(Shared_Ptr& rhs)\r
+               {\r
+                  std::swap(m_ptr, rhs.m_ptr);\r
+                  std::swap(m_count, rhs.m_count);\r
+               }\r
+\r
+               Shared_Ptr& operator=(const Shared_Ptr& rhs)\r
+               {\r
+                        Shared_Ptr tmp(rhs);\r
+                        this->swap(tmp);\r
+                        return *this;\r
+               }\r
+\r
+               T1* operator->() const\r
+               {\r
+                       assert(m_ptr);\r
+                       return m_ptr;\r
+               }\r
+\r
+               T1& operator*() const\r
+               {\r
+                       assert (m_ptr);\r
+                       return *m_ptr;\r
+               }\r
+\r
+               bool operator== (const Shared_Ptr& rhs) const\r
+               {\r
+                       return ( *m_ptr == *rhs.m_ptr);\r
+               }\r
+\r
+               bool operator!= (const Shared_Ptr& rhs) const\r
+               {\r
+                       return ( *m_ptr != *rhs.m_ptr);\r
+               }\r
+\r
+               bool operator< (const Shared_Ptr& rhs) const\r
+               {\r
+                       return ( *m_ptr < *rhs.m_ptr );\r
+               }\r
+\r
+               bool operator> (const Shared_Ptr& rhs) const\r
+               {\r
+                       return ( *m_ptr > *rhs.m_ptr );\r
+               }\r
+\r
+       private:\r
+               void inc_ref()\r
+               {\r
+                       if(m_count)\r
+                               InterlockedIncrement(m_count);\r
+               }\r
+\r
+               int  dec_ref()\r
+               {\r
+                       assert (m_count);\r
+                       return InterlockedDecrement(m_count);\r
+               }\r
+\r
+               T1* m_ptr;\r
+               long* m_count;\r
+       };\r
+\r
+}\r
+\r
+#endif // _WIN32XX_SHARED_PTR_\r

UCC git Repository :: git.ucc.asn.au