1// error_code_user_test.cpp ------------------------------------------------//
2
3// Copyright Beman Dawes 2006
4
5// Distributed under the Boost Software License, Version 1.0. (See accompanying
6// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8// See library home page at http://www.boost.org/libs/system
9
10// ------------------------------------------------------------------------ //
11
12// This program demonstrates creation and use of new categories of error
13// codes. Several scenarios are demonstrated and tested.
14
15// Motivation was a Boost posting by Christopher Kohlhoff on June 28, 2006.
16
17#include <boost/system/error_code.hpp>
18#include <boost/cerrno.hpp>
19#include <string>
20#include <cstdio>
21#include <boost/detail/lightweight_test.hpp>
22
23#ifdef BOOST_POSIX_API
24# include <sys/stat.h>
25#else
26# include <windows.h>
27#endif
28
29// ------------------------------------------------------------------------ //
30
31// Library 1: User function passes through an error code from the
32// operating system.
33
34
35boost::system::error_code my_mkdir( const std::string & path )
36{
37 return boost::system::error_code(
38# ifdef BOOST_POSIX_API
39 ::mkdir( path: path.c_str(), S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH ) == 0 ? 0 : errno,
40# else
41 ::CreateDirectoryA( path.c_str(), 0 ) != 0 ? 0 : ::GetLastError(),
42# endif
43 boost::system::system_category() );
44}
45
46// ------------------------------------------------------------------------ //
47
48// Library 2: User function passes through errno from the C-runtime.
49
50#include <cstdio>
51
52boost::system::error_code my_remove( const std::string & path )
53{
54 return boost::system::error_code(
55 std::remove( filename: path.c_str() ) == 0 ? 0 : errno,
56 boost::system::generic_category() ); // OK for both Windows and POSIX
57 // Alternatively, could use generic_category()
58 // on Windows and system_category() on
59 // POSIX-based systems.
60}
61
62// ------------------------------------------------------------------------ //
63
64// Library 3: Library uses enum to identify library specific errors.
65
66// This particular example is for a library within the parent namespace. For
67// an example of a library not within the parent namespace, see library 4.
68
69// header lib3.hpp:
70
71namespace boost
72{
73 namespace lib3
74 {
75 // lib3 has its own error_category:
76 const boost::system::error_category & get_lib3_error_category() BOOST_SYSTEM_NOEXCEPT;
77 const boost::system::error_category & lib3_error_category = get_lib3_error_category();
78
79 enum error
80 {
81 boo_boo=123,
82 big_boo_boo
83 };
84 }
85
86 namespace system
87 {
88 template<> struct is_error_code_enum<boost::lib3::error>
89 { static const bool value = true; };
90 }
91
92 namespace lib3
93 {
94 inline boost::system::error_code make_error_code(error e)
95 { return boost::system::error_code(e,lib3_error_category); }
96 }
97
98}
99
100// implementation file lib3.cpp:
101
102// #include <lib3.hpp>
103
104namespace boost
105{
106 namespace lib3
107 {
108 class lib3_error_category_imp : public boost::system::error_category
109 {
110 public:
111 lib3_error_category_imp() : boost::system::error_category() { }
112
113 const char * name() const BOOST_SYSTEM_NOEXCEPT
114 {
115 return "lib3";
116 }
117
118 boost::system::error_condition default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT
119 {
120 return ev == boo_boo
121 ? boost::system::error_condition( boost::system::errc::io_error,
122 boost::system::generic_category() )
123 : boost::system::error_condition( ev,
124 boost::lib3::lib3_error_category );
125 }
126
127 std::string message( int ev ) const
128 {
129 if ( ev == boo_boo ) return std::string("boo boo");
130 if ( ev == big_boo_boo ) return std::string("big boo boo");
131 return std::string("unknown error");
132 }
133
134 };
135
136 const boost::system::error_category & get_lib3_error_category() BOOST_SYSTEM_NOEXCEPT
137 {
138 static const lib3_error_category_imp l3ecat;
139 return l3ecat;
140 }
141 }
142}
143
144// ------------------------------------------------------------------------ //
145
146// Library 4: Library uses const error_code's to identify library specific
147// errors.
148
149// This particular example is for a library not within the parent namespace.
150// For an example of a library within the parent namespace, see library 3.
151
152// header lib4.hpp:
153
154namespace lib4
155{
156 // lib4 has its own error_category:
157 const boost::system::error_category & get_lib4_error_category() BOOST_SYSTEM_NOEXCEPT;
158 const boost::system::error_category & lib4_error_category = get_lib4_error_category();
159
160 extern const boost::system::error_code boo_boo;
161 extern const boost::system::error_code big_boo_boo;
162}
163
164// implementation file lib4.cpp:
165
166// #include <lib4.hpp>
167
168namespace lib4
169{
170 class lib4_error_category_imp : public boost::system::error_category
171 {
172 public:
173 lib4_error_category_imp() : boost::system::error_category() { }
174
175 const char * name() const BOOST_SYSTEM_NOEXCEPT
176 {
177 return "lib4";
178 }
179
180 boost::system::error_condition default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT
181 {
182 return ev == boo_boo.value()
183 ? boost::system::error_condition( boost::system::errc::io_error,
184 boost::system::generic_category() )
185 : boost::system::error_condition( ev, lib4::lib4_error_category );
186 }
187
188 std::string message( int ev ) const
189 {
190 if ( ev == boo_boo.value() ) return std::string("boo boo");
191 if ( ev == big_boo_boo.value() ) return std::string("big boo boo");
192 return std::string("unknown error");
193 }
194 };
195
196 const boost::system::error_category & get_lib4_error_category() BOOST_SYSTEM_NOEXCEPT
197 {
198 static const lib4_error_category_imp l4ecat;
199 return l4ecat;
200 }
201
202 const boost::system::error_code boo_boo( 456, lib4_error_category );
203 const boost::system::error_code big_boo_boo( 789, lib4_error_category );
204
205}
206
207// ------------------------------------------------------------------------ //
208
209// Chris Kolhoff's Test3, modified to work with error_code.hpp
210
211// Test3
212// =====
213// Define error classes to check for success, permission_denied and
214// out_of_memory, but add additional mappings for a user-defined error category.
215//
216
217//namespace test3 {
218
219// enum user_err
220// {
221// user_success = 0,
222// user_permission_denied,
223// user_out_of_memory
224// };
225//
226// class user_error_category_imp : public boost::system::error_category
227// {
228// public:
229// const std::string & name() const
230// {
231// static std::string s( "test3" );
232// return s;
233// }
234//
235// boost::system::error_code portable_error_code( int ev ) const
236// {
237// switch (ev)
238// {
239// case user_success:
240// return boost::system::error_code(boost::system::errc::success, boost::system::generic_category());
241// case user_permission_denied:
242// return boost::system::error_code(boost::system::errc::permission_denied, boost::system::generic_category());
243// case user_out_of_memory:
244// return boost::system::error_code(boost::system::errc::not_enough_memory, boost::system::generic_category());
245// default:
246// break;
247// }
248// return boost::system::error_code(boost::system::errc::no_posix_equivalent, boost::system::generic_category());
249// }
250//
251// };
252//
253// const user_error_category_imp user_error_category_const;
254//
255// const boost::system::error_category & user_error_category
256// = user_error_category_const;
257//
258// template<> inline boost::system::error_code make_error_code(user_err e)
259// {
260// return boost::system::error_code(e, user_error_category);
261// }
262//
263// // test code
264//
265// void check_success(const boost::system::error_code& ec, bool expect)
266// {
267// BOOST_TEST( (ec == boost::system::errc::success) == expect );
268// if (ec == boost::system::errc::success)
269// std::cout << "yes... " << (expect ? "ok" : "fail") << '\n';
270// else
271// std::cout << "no... " << (expect ? "fail" : "ok") << '\n';
272// }
273//
274// void check_permission_denied(const boost::system::error_code& ec, bool expect)
275// {
276// BOOST_TEST( (ec == boost::system::errc::permission_denied) == expect );
277// if (ec == boost::system::errc::permission_denied)
278// std::cout << "yes... " << (expect ? "ok" : "fail") << '\n';
279// else
280// std::cout << "no... " << (expect ? "fail" : "ok") << '\n';
281// }
282//
283// void check_out_of_memory(const boost::system::error_code& ec, bool expect)
284// {
285// BOOST_TEST( (ec == boost::system::errc::not_enough_memory) == expect );
286// if (ec == boost::system::errc::not_enough_memory)
287// std::cout << "yes... " << (expect ? "ok" : "fail") << '\n';
288// else
289// std::cout << "no... " << (expect ? "fail" : "ok") << '\n';
290// }
291//
292// void run()
293// {
294// printf("Test3\n");
295// printf("=====\n");
296// boost::system::error_code ec;
297// check_success(ec, true);
298// check_success(boost::system::errc::success, true);
299// check_success(boost::system::errc::permission_denied, false);
300// check_success(boost::system::errc::not_enough_memory, false);
301// check_success(user_success, true);
302// check_success(user_permission_denied, false);
303// check_success(user_out_of_memory, false);
304// check_permission_denied(ec, false);
305// check_permission_denied(boost::system::errc::success, false);
306// check_permission_denied(boost::system::errc::permission_denied, true);
307// check_permission_denied(boost::system::errc::not_enough_memory, false);
308// check_permission_denied(user_success, false);
309// check_permission_denied(user_permission_denied, true);
310// check_permission_denied(user_out_of_memory, false);
311// check_out_of_memory(ec, false);
312// check_out_of_memory(boost::system::errc::success, false);
313// check_out_of_memory(boost::system::errc::permission_denied, false);
314// check_out_of_memory(boost::system::errc::not_enough_memory, true);
315// check_out_of_memory(user_success, false);
316// check_out_of_memory(user_permission_denied, false);
317// check_out_of_memory(user_out_of_memory, true);
318//
319//# ifdef BOOST_WINDOWS_API
320// check_success(boost::system::windows::success, true);
321// check_success(boost::system::windows::access_denied, false);
322// check_success(boost::system::windows::not_enough_memory, false);
323// check_permission_denied(boost::system::windows::success, false);
324// check_permission_denied(boost::system::windows::access_denied, true);
325// check_permission_denied(boost::system::windows::not_enough_memory, false);
326// check_out_of_memory(boost::system::windows::success, false);
327// check_out_of_memory(boost::system::windows::access_denied, false);
328// check_out_of_memory(boost::system::windows::not_enough_memory, true);
329//# endif
330//
331// printf("\n");
332// }
333//
334//} // namespace test3
335
336
337
338// ------------------------------------------------------------------------ //
339
340int main( int, char *[] )
341{
342 boost::system::error_code ec;
343
344 // Library 1 tests:
345
346 ec = my_mkdir( path: "/no-such-file-or-directory/will-not-succeed" );
347 std::cout << "ec.value() is " << ec.value() << '\n';
348
349 BOOST_TEST( ec );
350 BOOST_TEST( ec == boost::system::errc::no_such_file_or_directory );
351 BOOST_TEST( ec.category() == boost::system::system_category() );
352
353 // Library 2 tests:
354
355 ec = my_remove( path: "/no-such-file-or-directory" );
356 std::cout << "ec.value() is " << ec.value() << '\n';
357
358 BOOST_TEST( ec );
359 BOOST_TEST( ec == boost::system::errc::no_such_file_or_directory );
360 BOOST_TEST( ec.category() == boost::system::generic_category() );
361
362 // Library 3 tests:
363
364 ec = boost::lib3::boo_boo;
365 std::cout << "ec.value() is " << ec.value() << '\n';
366
367 BOOST_TEST( ec );
368 BOOST_TEST( ec == boost::lib3::boo_boo );
369 BOOST_TEST( ec.value() == boost::lib3::boo_boo );
370 BOOST_TEST( ec.category() == boost::lib3::lib3_error_category );
371
372 BOOST_TEST( ec == boost::system::errc::io_error );
373
374 boost::system::error_code ec3( boost::lib3::boo_boo+100,
375 boost::lib3::lib3_error_category );
376 BOOST_TEST( ec3.category() == boost::lib3::lib3_error_category );
377 BOOST_TEST( ec3.default_error_condition().category()
378 == boost::lib3::lib3_error_category );
379
380 // Library 4 tests:
381
382 ec = lib4::boo_boo;
383 std::cout << "ec.value() is " << ec.value() << '\n';
384
385 BOOST_TEST( ec );
386 BOOST_TEST( ec == lib4::boo_boo );
387 BOOST_TEST( ec.value() == lib4::boo_boo.value() );
388 BOOST_TEST( ec.category() == lib4::lib4_error_category );
389
390 BOOST_TEST( ec == boost::system::errc::io_error );
391
392 boost::system::error_code ec4( lib4::boo_boo.value()+100,
393 lib4::lib4_error_category );
394 BOOST_TEST( ec4.default_error_condition().category()
395 == lib4::lib4_error_category );
396
397 // Test 3
398
399 //test3::run();
400
401 return ::boost::report_errors();
402}
403

source code of boost/libs/system/test/error_code_user_test.cpp