Added SENF_NO_DEBUG symbol and removed dependency on NDEBUG
[senf.git] / Socket / SocketHandle.cti
1 // $Id$
2 //
3 // Copyright (C) 2006
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 SocketHandle inline template implementation
25  */
26
27 #include "SocketHandle.ih"
28
29 // Custom includes
30 #include "../Utils/senfassert.hh"
31 #include <typeinfo>
32 #include <boost/lexical_cast.hpp>
33 #include "../Utils/TypeInfo.hh"
34
35 #define prefix_ inline
36 ///////////////////////////////cti.p///////////////////////////////////////
37
38 template <class SocketPolicy>
39 prefix_ senf::SocketHandle<SocketPolicy>::SocketHandle()
40 {}
41
42 template <class SocketPolicy>
43 template <class OtherPolicy>
44 prefix_ senf::SocketHandle<SocketPolicy>::SocketHandle(SocketHandle<OtherPolicy> other,
45                                                               typename IsCompatible<OtherPolicy>::type *)
46     : FileHandle(other)
47 {}
48
49 template <class SocketPolicy>
50 template <class OtherPolicy>
51 prefix_ typename senf::SocketHandle<SocketPolicy>::template IsCompatible<OtherPolicy>::type const &
52 senf::SocketHandle<SocketPolicy>::operator=(SocketHandle<OtherPolicy> other)
53 {
54     assign(other);
55     return *this;
56 }
57
58 template <class SocketPolicy>
59 prefix_
60 senf::SocketHandle<SocketPolicy>::SocketHandle(std::auto_ptr<SocketProtocol> protocol,
61                                                       bool isServer)
62     : FileHandle(std::auto_ptr<FileBody>(new SocketBody(protocol,isServer)))
63 {}
64
65 template <class SocketPolicy>
66 prefix_ senf::SocketHandle<SocketPolicy>::SocketHandle(FileHandle other, bool isChecked)
67     : FileHandle(other)
68 {
69     SENF_ASSERT( isChecked );
70     SENF_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()) );
71 }
72
73 template <class SocketPolicy>
74 prefix_ senf::SocketBody & senf::SocketHandle<SocketPolicy>::body()
75 {
76     SENF_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()) );
77     return static_cast<SocketBody &>(FileHandle::body());
78 }
79
80 template <class SocketPolicy>
81 prefix_ senf::SocketBody const & senf::SocketHandle<SocketPolicy>::body()
82     const
83 {
84     SENF_ASSERT( dynamic_cast<SocketBody const *>(&FileHandle::body()) );
85     return static_cast<SocketBody const &>(FileHandle::body());
86 }
87
88 template <class SocketPolicy>
89 prefix_ senf::SocketProtocol const & senf::SocketHandle<SocketPolicy>::protocol()
90     const
91 {
92     return body().protocol();
93 }
94
95 template <class SocketPolicy>
96 prefix_ void senf::SocketHandle<SocketPolicy>::assign(FileHandle other)
97 {
98     FileHandle::operator=(other);
99 }
100
101 template <class SocketPolicy>
102 prefix_ senf::SocketHandle<SocketPolicy>
103 senf::SocketHandle<SocketPolicy>::cast_static(FileHandle handle)
104 {
105     return SocketHandle(handle,true);
106 }
107
108 template <class SocketPolicy>
109 prefix_ senf::SocketHandle<SocketPolicy>
110 senf::SocketHandle<SocketPolicy>::cast_dynamic(FileHandle handle)
111 {
112     // throws bad_cast if the body is not a SocketBody
113     SocketBody & body (dynamic_cast<SocketBody&>(FileHandle::body(handle)));
114     // throws bad_cast if the policy is not compatible
115     SocketPolicy::checkBaseOf(body.protocol().policy());
116     return cast_static(handle);
117 }
118
119 template <class Target, class Source>
120 prefix_ Target senf::static_socket_cast(Source handle)
121 {
122     BOOST_STATIC_ASSERT((
123         boost::is_convertible<Source*,FileHandle*>::value &&
124         boost::is_convertible<Target*,FileHandle*>::value &&
125         ( boost::is_convertible<Source,Target>::value ||
126           boost::is_convertible<Target,Source>::value ) ));
127     SENF_ASSERT( check_socket_cast<Target>(handle) );
128     return Target::cast_static(handle);
129 }
130
131 template <class Target, class Source>
132 prefix_ Target senf::dynamic_socket_cast(Source handle)
133 {
134     BOOST_STATIC_ASSERT((
135         boost::is_convertible<Source*,FileHandle*>::value &&
136         boost::is_convertible<Target*,FileHandle*>::value &&
137         ( boost::is_convertible<Source,Target>::value ||
138           boost::is_convertible<Target,Source>::value ) ));
139     return Target::cast_dynamic(handle);
140 }
141
142 template <class Target, class Source>
143 prefix_ bool senf::check_socket_cast(Source handle)
144 {
145     BOOST_STATIC_ASSERT((
146         boost::is_convertible<Source*,FileHandle*>::value &&
147         boost::is_convertible<Target*,FileHandle*>::value &&
148         ( boost::is_convertible<Source,Target>::value ||
149           boost::is_convertible<Target,Source>::value ) ));
150     // we don't have a non-throwing variant of cast_dynamic
151     // for two reasons:
152     // a) since the handle is passed back by value, we cannot return
153     //    something like a null handle
154     // b) it is simpler to implement cast_dynamic throwig bad_cast on
155     //    failure than implementing cast_check
156     try {
157         Target::cast_dynamic(handle);
158     }
159     catch (std::bad_cast const &) {
160         return false;
161     }
162     return true;
163 }
164
165 template <class SocketPolicy>
166 prefix_ void senf::SocketHandle<SocketPolicy>::state(SocketStateMap & map, unsigned lod)
167 {
168     // We use typeid here even though the type of *this is static
169     // (SocketHandle is not polymorphic and has no vtable). This will
170     // automatically include the SocketPolicy template parameter in
171     // the type name and therefore show the \e static policy of the
172     // socket handle.
173     map["handle"] << prettyName(typeid(*this));
174     body().state(map,lod);
175 }
176
177 template <class SocketPolicy>
178 prefix_ std::string senf::SocketHandle<SocketPolicy>::dumpState(unsigned lod)
179 {
180     SocketStateMap map;
181     state(map,lod);
182     return detail::dumpState(map);
183 }
184
185 ///////////////////////////////cti.e///////////////////////////////////////
186 #undef prefix_
187
188 \f
189 // Local Variables:
190 // mode: c++
191 // fill-column: 100
192 // c-file-style: "senf"
193 // indent-tabs-mode: nil
194 // ispell-local-dictionary: "american"
195 // compile-command: "scons -u test"
196 // comment-column: 40
197 // End: