Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
4.0 KiB

  1. //--------------------------------------------------------------------
  2. // Specialized allocator which throws exceptions if memory allocation fails.
  3. //
  4. // Copyright (C) Microsoft Corporation, 2000-2001
  5. //
  6. // Created by: Duncan Bryce (duncanb), 12-03-2001
  7. //
  8. #ifndef MY_STL_ALLOC_H
  9. #define MY_STL_ALLOC_H 1
  10. //--------------------------------------------------------------------------------
  11. //
  12. // ***NOTE***
  13. //
  14. // MyThrowingAllocator is designed to overcome a problem with VC6. Namely,
  15. // that "new" returns NULL and doesn't throw an exception. This causes all STL
  16. // algorithms which allocate memory to fail silently when memory is exhausted,
  17. // thereby leaving some STL components in an invalid state. MyThrowingAllocator,
  18. // on the other hand, will throw an exception before internal state of the
  19. // object is modified.
  20. //
  21. // *** THIS SHOULD BE REMOVED ONCE THE BUILD LAB MOVES TO VC7 ***
  22. //
  23. template <class T>
  24. class MyThrowingAllocator {
  25. public:
  26. //--------------------------------------------------------------------------------
  27. //
  28. // Boilerplate stuff required by STL:
  29. //
  30. //--------------------------------------------------------------------------------
  31. typedef T value_type;
  32. typedef T* pointer;
  33. typedef const T* const_pointer;
  34. typedef T& reference;
  35. typedef const T& const_reference;
  36. typedef size_t size_type;
  37. typedef ptrdiff_t difference_type;
  38. pointer address (reference value) const { return &value; }
  39. const_pointer address (const_reference value) const { return &value; }
  40. MyThrowingAllocator() {}
  41. MyThrowingAllocator(const MyThrowingAllocator&) {}
  42. template <class U> MyThrowingAllocator (const MyThrowingAllocator<U>&) {}
  43. ~MyThrowingAllocator() {}
  44. size_t max_size() const {
  45. size_t _N = (size_t)(-1) / sizeof (T);
  46. return (0 < _N ? _N : 1);
  47. }
  48. //--------------------------------------------------------------------------------
  49. //
  50. // Implementation of our throwing allocator.
  51. //
  52. //--------------------------------------------------------------------------------
  53. // Allocate memory for the specified number of elements.
  54. // OF NOTE:
  55. // 1) num == number of elements of size sizeof(T) to allocate
  56. // 2) the elements should be *allocated* only (not initialized)
  57. pointer allocate (size_type cElements, const void *pvIgnored = 0) {
  58. return (pointer)_Charalloc(sizeof(T)*cElements);
  59. }
  60. // SPEC ERROR: This is necessary because VC6 can't compile "rebind" (the preferred way of
  61. // acquiring new allocators from an allocator reference). We need to provide
  62. // the next best thing, an allocator which allocates in units of bytes:
  63. char *_Charalloc(size_type _N) {
  64. void *pvResult = LocalAlloc(LPTR, _N);
  65. if (NULL == pvResult) {
  66. throw std::bad_alloc();
  67. }
  68. return (char *)pvResult;
  69. }
  70. // Initialize an element of allocated memory with the specified value.
  71. void construct (pointer pData, const T& value) {
  72. // Use C++'s "placement new". It calls the constructor on uninitialized data at the specified address
  73. new (pData) T(value);
  74. }
  75. // Destruct the supplied object
  76. void destroy (pointer pObject) {
  77. pObject->~T();
  78. }
  79. // Free memory for the (presumably destructed) object.
  80. // SPEC ERROR: As before, because we don't know what type of data we'll be allocating,
  81. // so do something nonstandard, and declare the deallocator as taking a void *.
  82. void deallocate (void *pData, size_type cIgnored) {
  83. LocalFree(pData);
  84. }
  85. };
  86. template <class T1, class T2> inline
  87. bool operator== (const MyThrowingAllocator<T1>&, const MyThrowingAllocator<T2>&) {
  88. return true;
  89. }
  90. template <class T1, class T2> inline
  91. bool operator!= (const MyThrowingAllocator<T1>&, const MyThrowingAllocator<T2>&) {
  92. return false;
  93. }
  94. #endif // MY_STL_ALLOC_H