28acd080946afdf2111ee28a6b57ec8bb5d451cb
[senf.git] / senf / Utils / pimpl_ptr.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2010
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief pimpl_ptr.test unit tests */
25
26 //#include "pimpl_ptr.test.hh"
27 //#include "pimpl_ptr.test.ih"
28
29 // Custom includes
30 #include "pimpl_ptr.hh"
31
32 #include <senf/Utils/auto_unit_test.hh>
33 #include <boost/test/test_tools.hpp>
34
35 #define prefix_
36 ///////////////////////////////cc.p////////////////////////////////////////
37
38 namespace {
39
40     struct PimplTest
41     {
42         struct Impl;
43         senf::pimpl_ptr<Impl> impl_;
44
45         explicit PimplTest(int v);
46     };
47
48     unsigned implConstruct (0);
49     unsigned implClone (0);
50     unsigned implDestroy (0);
51
52     struct PimplTest::Impl
53     {
54         Impl(int v) : value (v) { ++ implConstruct; }
55         Impl(Impl const & other) : value (other.value) { ++ implClone; }
56         ~Impl() { ++ implDestroy; }
57
58         int value;
59     };
60
61     prefix_ PimplTest::PimplTest(int v)
62         : impl_ (new Impl(v))
63     {}
64
65 }
66
67 BOOST_AUTO_UNIT_TEST(pimpl_ptr)
68 {
69     {
70         PimplTest ob1 (1);
71         PimplTest ob2 (ob1);
72         PimplTest ob3 (3);
73
74         BOOST_CHECK_EQUAL( implConstruct, 2u );
75         BOOST_CHECK_EQUAL( implClone, 1u );
76         BOOST_CHECK_EQUAL( implDestroy, 0u );
77
78         BOOST_CHECK( ob1.impl_.get() != ob2.impl_.get() );
79         BOOST_CHECK( ob2.impl_.get() != ob3.impl_.get() );
80         BOOST_CHECK( ob3.impl_.get() != ob1.impl_.get() );
81
82         BOOST_CHECK_EQUAL( ob1.impl_->value, 1 );
83         BOOST_CHECK_EQUAL( ob2.impl_->value, 1 );
84         BOOST_CHECK_EQUAL( ob3.impl_->value, 3 );
85
86         ob3 = ob1;
87
88         BOOST_CHECK_EQUAL( implConstruct, 2u );
89         BOOST_CHECK_EQUAL( implClone, 2u );
90         BOOST_CHECK_EQUAL( implDestroy, 1u );
91
92         BOOST_CHECK( ob3.impl_.get() != ob1.impl_.get() );
93
94         BOOST_CHECK_EQUAL( ob1.impl_->value, 1 );
95         BOOST_CHECK_EQUAL( ob3.impl_->value, 1 );
96
97         ob3.impl_->value = 3;
98
99         BOOST_CHECK_EQUAL( ob1.impl_->value, 1 );
100         BOOST_CHECK_EQUAL( ob3.impl_->value, 3 );
101
102         struct PimplTest::Impl * p1 (ob1.impl_.get());
103         struct PimplTest::Impl * p3 (ob3.impl_.get());
104
105         std::swap(ob3.impl_, ob1.impl_);
106
107         BOOST_CHECK_EQUAL( implConstruct, 2u );
108         BOOST_CHECK_EQUAL( implClone, 2u );
109         BOOST_CHECK_EQUAL( implDestroy, 1u );
110
111         BOOST_CHECK_EQUAL( ob1.impl_->value, 3 );
112         BOOST_CHECK_EQUAL( ob3.impl_->value, 1 );
113
114         BOOST_CHECK_EQUAL( ob1.impl_.get(), p3 );
115         BOOST_CHECK_EQUAL( ob3.impl_.get(), p1 );
116     }
117
118     BOOST_CHECK_EQUAL( implConstruct, 2u );
119     BOOST_CHECK_EQUAL( implClone, 2u );
120     BOOST_CHECK_EQUAL( implDestroy, 4u );
121 }
122
123 #ifdef COMPILE_CHECK
124
125 namespace {
126
127     // We need this template arg to delay the constructor instantiation
128     // until within COMPILE_FAIL. Otherwise the CompileCheck builder has no
129     // way to associate the error message with the test ...
130     template <class Delay=void>
131     struct PimplTestIncomplete
132     {
133         struct Impl;
134         senf::pimpl_ptr<Impl> impl_;
135         PimplTestIncomplete() : impl_ (0) {}
136     };
137
138 }
139
140 COMPILE_FAIL(pimpl_ptr_incomplete)
141 {
142     PimplTestIncomplete<> ob;
143 }
144
145 #endif
146
147 ///////////////////////////////cc.e////////////////////////////////////////
148 #undef prefix_
149
150 \f
151 // Local Variables:
152 // mode: c++
153 // fill-column: 100
154 // comment-column: 40
155 // c-file-style: "senf"
156 // indent-tabs-mode: nil
157 // ispell-local-dictionary: "american"
158 // compile-command: "scons -u test"
159 // End: