switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / pimpl_ptr.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2010
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief pimpl_ptr.test unit tests */
30
31 //#include "pimpl_ptr.test.hh"
32 //#include "pimpl_ptr.test.ih"
33
34 // Custom includes
35 #include "pimpl_ptr.hh"
36
37 #include <senf/Utils/auto_unit_test.hh>
38 #include <boost/test/test_tools.hpp>
39
40 #define prefix_
41 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42
43 namespace {
44
45     struct PimplTest
46     {
47         struct Impl;
48         senf::pimpl_ptr<Impl> impl_;
49
50         explicit PimplTest(int v);
51     };
52
53     unsigned implConstruct (0);
54     unsigned implClone (0);
55     unsigned implDestroy (0);
56
57     struct PimplTest::Impl
58     {
59         Impl(int v) : value (v) { ++ implConstruct; }
60         Impl(Impl const & other) : value (other.value) { ++ implClone; }
61         ~Impl() { ++ implDestroy; }
62
63         int value;
64     };
65
66     prefix_ PimplTest::PimplTest(int v)
67         : impl_ (new Impl(v))
68     {}
69
70 }
71
72 BOOST_AUTO_UNIT_TEST(pimpl_ptr)
73 {
74     {
75         PimplTest ob1 (1);
76         PimplTest ob2 (ob1);
77         PimplTest ob3 (3);
78
79         BOOST_CHECK_EQUAL( implConstruct, 2u );
80         BOOST_CHECK_EQUAL( implClone, 1u );
81         BOOST_CHECK_EQUAL( implDestroy, 0u );
82
83         BOOST_CHECK( ob1.impl_.get() != ob2.impl_.get() );
84         BOOST_CHECK( ob2.impl_.get() != ob3.impl_.get() );
85         BOOST_CHECK( ob3.impl_.get() != ob1.impl_.get() );
86
87         BOOST_CHECK_EQUAL( ob1.impl_->value, 1 );
88         BOOST_CHECK_EQUAL( ob2.impl_->value, 1 );
89         BOOST_CHECK_EQUAL( ob3.impl_->value, 3 );
90
91         ob3 = ob1;
92
93         BOOST_CHECK_EQUAL( implConstruct, 2u );
94         BOOST_CHECK_EQUAL( implClone, 2u );
95         BOOST_CHECK_EQUAL( implDestroy, 1u );
96
97         BOOST_CHECK( ob3.impl_.get() != ob1.impl_.get() );
98
99         BOOST_CHECK_EQUAL( ob1.impl_->value, 1 );
100         BOOST_CHECK_EQUAL( ob3.impl_->value, 1 );
101
102         ob3.impl_->value = 3;
103
104         BOOST_CHECK_EQUAL( ob1.impl_->value, 1 );
105         BOOST_CHECK_EQUAL( ob3.impl_->value, 3 );
106
107         struct PimplTest::Impl * p1 (ob1.impl_.get());
108         struct PimplTest::Impl * p3 (ob3.impl_.get());
109
110         std::swap(ob3.impl_, ob1.impl_);
111
112         BOOST_CHECK_EQUAL( implConstruct, 2u );
113         BOOST_CHECK_EQUAL( implClone, 2u );
114         BOOST_CHECK_EQUAL( implDestroy, 1u );
115
116         BOOST_CHECK_EQUAL( ob1.impl_->value, 3 );
117         BOOST_CHECK_EQUAL( ob3.impl_->value, 1 );
118
119         BOOST_CHECK_EQUAL( ob1.impl_.get(), p3 );
120         BOOST_CHECK_EQUAL( ob3.impl_.get(), p1 );
121     }
122
123     BOOST_CHECK_EQUAL( implConstruct, 2u );
124     BOOST_CHECK_EQUAL( implClone, 2u );
125     BOOST_CHECK_EQUAL( implDestroy, 4u );
126 }
127
128 #ifdef COMPILE_CHECK
129
130 namespace {
131
132     // We need this template arg to delay the constructor instantiation
133     // until within COMPILE_FAIL. Otherwise the CompileCheck builder has no
134     // way to associate the error message with the test ...
135     template <class Delay=void>
136     struct PimplTestIncomplete
137     {
138         struct Impl;
139         senf::pimpl_ptr<Impl> impl_;
140         PimplTestIncomplete() : impl_ (0) {}
141     };
142
143 }
144
145 COMPILE_FAIL(pimpl_ptr_incomplete)
146 {
147     PimplTestIncomplete<> ob;
148 }
149
150 #endif
151
152 //-/////////////////////////////////////////////////////////////////////////////////////////////////
153 #undef prefix_
154
155 \f
156 // Local Variables:
157 // mode: c++
158 // fill-column: 100
159 // comment-column: 40
160 // c-file-style: "senf"
161 // indent-tabs-mode: nil
162 // ispell-local-dictionary: "american"
163 // compile-command: "scons -u test"
164 // End: