aboutsummaryrefslogtreecommitdiff
path: root/odb/details/shared-ptr/base.hxx
blob: 5153aba822871d8f01f538f49f411807ab1fd72d (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
// file      : odb/details/shared-ptr/base.hxx
// copyright : Copyright (c) 2009-2017 Code Synthesis Tools CC
// license   : GNU GPL v2; see accompanying LICENSE file

#ifndef ODB_DETAILS_SHARED_PTR_BASE_HXX
#define ODB_DETAILS_SHARED_PTR_BASE_HXX

#include <odb/pre.hxx>

#include <odb/details/config.hxx> // ODB_CXX11, ODB_NOTHROW_NOEXCEPT

#include <new>
#include <cstddef>   // std::size_t

#ifdef ODB_CXX11
#include <atomic>
#endif

#include <odb/details/export.hxx>
#include <odb/details/shared-ptr/counter-type.hxx>

namespace odb
{
  namespace details
  {
    struct share
    {
      explicit
      share (char id);

      bool
      operator== (share) const;

    private:
      char id_;
    };

    extern LIBODB_EXPORT share shared;
    extern LIBODB_EXPORT share exclusive;
  }
}

#ifdef ODB_CXX11
LIBODB_EXPORT void*
operator new (std::size_t, odb::details::share);
#else
LIBODB_EXPORT void*
operator new (std::size_t, odb::details::share) throw (std::bad_alloc);
#endif

LIBODB_EXPORT void
operator delete (void*, odb::details::share) ODB_NOTHROW_NOEXCEPT;

namespace odb
{
  namespace details
  {
    class LIBODB_EXPORT shared_base
    {
    public:
      shared_base ();
      shared_base (const shared_base&);
      shared_base&
      operator= (const shared_base&);

      void
      _inc_ref ();

      bool
      _dec_ref ();

      std::size_t
      _ref_count () const;

#ifdef ODB_CXX11
      void*
      operator new (std::size_t);

      void*
      operator new (std::size_t, share);
#else
      void*
      operator new (std::size_t) throw (std::bad_alloc);

      void*
      operator new (std::size_t, share) throw (std::bad_alloc);
#endif

      void
      operator delete (void*, share) ODB_NOTHROW_NOEXCEPT;

      void
      operator delete (void*) ODB_NOTHROW_NOEXCEPT;

      struct refcount_callback
      {
        void* arg;

        // Return true if the object should be deleted, false otherwise.
        //
        bool (*zero_counter) (void*);
      };

    protected:
#ifdef ODB_CXX11
      std::atomic<std::size_t> counter_;
#else
      std::size_t counter_;
#endif
      refcount_callback* callback_;
    };

    template <typename X>
    inline X*
    inc_ref (X*);

    template <typename X>
    inline void
    dec_ref (X*);

    template <typename X>
    inline std::size_t
    ref_count (const X*);
  }
}

#include <odb/details/shared-ptr/base.ixx>
#include <odb/details/shared-ptr/base.txx>

#include <odb/post.hxx>

#endif // ODB_DETAILS_SHARED_PTR_BASE_HXX