summaryrefslogtreecommitdiffstats
blob: 3c1692d0e11fdb3a04236fa32705341f06920c23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/thread for documentation.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef BOOST_THREAD_DETAIL_MEMORY_HPP
#define BOOST_THREAD_DETAIL_MEMORY_HPP

#include <boost/config.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/scoped_allocator.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_scalar.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>

namespace boost
{
  namespace thread_detail
  {
    template <class _Alloc>
    class allocator_destructor
    {
      typedef container::allocator_traits<_Alloc> alloc_traits;
    public:
      typedef typename alloc_traits::pointer pointer;
      typedef typename alloc_traits::size_type size_type;
    private:
      _Alloc alloc_;
      size_type s_;
    public:
      allocator_destructor(_Alloc& a, size_type s)BOOST_NOEXCEPT
      : alloc_(a), s_(s)
      {}
      void operator()(pointer p)BOOST_NOEXCEPT
      {
        alloc_traits::destroy(alloc_, p);
        alloc_traits::deallocate(alloc_, p, s_);
      }
    };
  } //namespace thread_detail

  typedef container::allocator_arg_t allocator_arg_t;
  BOOST_CONSTEXPR_OR_CONST allocator_arg_t allocator_arg = {};

  template <class T, class Alloc>
  struct uses_allocator: public container::uses_allocator<T, Alloc>
  {
  };

  template <class Ptr>
  struct pointer_traits
  {
      typedef Ptr pointer;
//      typedef <details> element_type;
//      typedef <details> difference_type;

//      template <class U> using rebind = <details>;
//
//      static pointer pointer_to(<details>);
  };

  template <class T>
  struct pointer_traits<T*>
  {
      typedef T* pointer;
      typedef T element_type;
      typedef ptrdiff_t difference_type;

//      template <class U> using rebind = U*;
//
//      static pointer pointer_to(<details>) noexcept;
  };


  namespace thread_detail {
    template <class _Ptr1, class _Ptr2,
              bool = is_same<typename remove_cv<typename pointer_traits<_Ptr1>::element_type>::type,
                             typename remove_cv<typename pointer_traits<_Ptr2>::element_type>::type
                            >::value
             >
    struct same_or_less_cv_qualified_imp
        : is_convertible<_Ptr1, _Ptr2> {};

    template <class _Ptr1, class _Ptr2>
    struct same_or_less_cv_qualified_imp<_Ptr1, _Ptr2, false>
        : false_type {};

    template <class _Ptr1, class _Ptr2, bool = is_scalar<_Ptr1>::value &&
                                             !is_pointer<_Ptr1>::value>
    struct same_or_less_cv_qualified
        : same_or_less_cv_qualified_imp<_Ptr1, _Ptr2> {};

    template <class _Ptr1, class _Ptr2>
    struct same_or_less_cv_qualified<_Ptr1, _Ptr2, true>
        : false_type {};

  }
  template <class T>
  struct BOOST_SYMBOL_VISIBLE default_delete
  {
  #ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
    BOOST_SYMBOL_VISIBLE
    BOOST_CONSTEXPR default_delete() = default;
  #else
    BOOST_SYMBOL_VISIBLE
    BOOST_CONSTEXPR default_delete() BOOST_NOEXCEPT {}
  #endif
    template <class U>
    BOOST_SYMBOL_VISIBLE
    default_delete(const default_delete<U>&,
                  typename enable_if<is_convertible<U*, T*> >::type* = 0) BOOST_NOEXCEPT {}
    BOOST_SYMBOL_VISIBLE
    void operator() (T* ptr) const BOOST_NOEXCEPT
    {
      BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "default_delete can not delete incomplete type");
      delete ptr;
    }
  };

  template <class T>
  struct BOOST_SYMBOL_VISIBLE default_delete<T[]>
  {
  public:
  #ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
    BOOST_SYMBOL_VISIBLE
    BOOST_CONSTEXPR default_delete() = default;
  #else
    BOOST_SYMBOL_VISIBLE
    BOOST_CONSTEXPR default_delete() BOOST_NOEXCEPT {}
  #endif
    template <class U>
    BOOST_SYMBOL_VISIBLE
    default_delete(const default_delete<U[]>&,
                   typename enable_if<thread_detail::same_or_less_cv_qualified<U*, T*> >::type* = 0) BOOST_NOEXCEPT {}
    template <class U>
    BOOST_SYMBOL_VISIBLE
    void operator() (U* ptr,
                     typename enable_if<thread_detail::same_or_less_cv_qualified<U*, T*> >::type* = 0) const BOOST_NOEXCEPT
    {
      BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "default_delete can not delete incomplete type");
      delete [] ptr;
    }
  };

} // namespace boost


#endif //  BOOST_THREAD_DETAIL_MEMORY_HPP