1
// error_code_user_test.cpp ------------------------------------------------//
3
// Copyright Beman Dawes 2006
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)
8
// See library home page at http://www.boost.org/libs/system
10
// ------------------------------------------------------------------------ //
12
// This program demonstrates creation and use of new categories of error
13
// codes. Several scenarios are demonstrated and tested.
15
// Motivation was a Boost posting by Christopher Kohlhoff on June 28, 2006.
17
#define BOOST_SYSTEM_NO_DEPRECATED
19
#include <boost/system/error_code.hpp>
20
#include <boost/cerrno.hpp>
23
#include <boost/detail/lightweight_test.hpp>
25
#ifdef BOOST_POSIX_API
26
# include <sys/stat.h>
31
// ------------------------------------------------------------------------ //
33
// Library 1: User function passes through an error code from the
37
boost::system::error_code my_mkdir( const std::string & path )
39
return boost::system::error_code(
40
# ifdef BOOST_POSIX_API
41
::mkdir( path.c_str(), S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH ) == 0 ? 0 : errno,
43
::CreateDirectoryA( path.c_str(), 0 ) != 0 ? 0 : ::GetLastError(),
45
boost::system::system_category() );
48
// ------------------------------------------------------------------------ //
50
// Library 2: User function passes through errno from the C-runtime.
54
boost::system::error_code my_remove( const std::string & path )
56
return boost::system::error_code(
57
std::remove( path.c_str() ) == 0 ? 0 : errno,
58
boost::system::generic_category() ); // OK for both Windows and POSIX
59
// Alternatively, could use generic_category()
60
// on Windows and system_category() on
61
// POSIX-based systems.
64
// ------------------------------------------------------------------------ //
66
// Library 3: Library uses enum to identify library specific errors.
68
// This particular example is for a library within the parent namespace. For
69
// an example of a library not within the parent namespace, see library 4.
77
// lib3 has its own error_category:
78
const boost::system::error_category & get_lib3_error_category();
79
const boost::system::error_category & lib3_error_category = get_lib3_error_category();
90
template<> struct is_error_code_enum<boost::lib3::error>
91
{ static const bool value = true; };
96
inline boost::system::error_code make_error_code(error e)
97
{ return boost::system::error_code(e,lib3_error_category); }
102
// implementation file lib3.cpp:
104
// #include <lib3.hpp>
110
class lib3_error_category_imp : public boost::system::error_category
113
lib3_error_category_imp() : boost::system::error_category() { }
115
const char * name() const
120
boost::system::error_condition default_error_condition( int ev ) const
123
? boost::system::error_condition( boost::system::errc::io_error,
124
boost::system::generic_category() )
125
: boost::system::error_condition( ev,
126
boost::lib3::lib3_error_category );
129
std::string message( int ev ) const
131
if ( ev == boo_boo ) return std::string("boo boo");
132
if ( ev == big_boo_boo ) return std::string("big boo boo");
133
return std::string("unknown error");
138
const boost::system::error_category & get_lib3_error_category()
140
static const lib3_error_category_imp l3ecat;
146
// ------------------------------------------------------------------------ //
148
// Library 4: Library uses const error_code's to identify library specific
151
// This particular example is for a library not within the parent namespace.
152
// For an example of a library within the parent namespace, see library 3.
158
// lib4 has its own error_category:
159
const boost::system::error_category & get_lib4_error_category();
160
const boost::system::error_category & lib4_error_category = get_lib4_error_category();
162
extern const boost::system::error_code boo_boo;
163
extern const boost::system::error_code big_boo_boo;
166
// implementation file lib4.cpp:
168
// #include <lib4.hpp>
172
class lib4_error_category_imp : public boost::system::error_category
175
lib4_error_category_imp() : boost::system::error_category() { }
177
const char * name() const
182
boost::system::error_condition default_error_condition( int ev ) const
184
return ev == boo_boo.value()
185
? boost::system::error_condition( boost::system::errc::io_error,
186
boost::system::generic_category() )
187
: boost::system::error_condition( ev, lib4::lib4_error_category );
190
std::string message( int ev ) const
192
if ( ev == boo_boo.value() ) return std::string("boo boo");
193
if ( ev == big_boo_boo.value() ) return std::string("big boo boo");
194
return std::string("unknown error");
198
const boost::system::error_category & get_lib4_error_category()
200
static const lib4_error_category_imp l4ecat;
204
const boost::system::error_code boo_boo( 456, lib4_error_category );
205
const boost::system::error_code big_boo_boo( 789, lib4_error_category );
209
// ------------------------------------------------------------------------ //
211
// Chris Kolhoff's Test3, modified to work with error_code.hpp
215
// Define error classes to check for success, permission_denied and
216
// out_of_memory, but add additional mappings for a user-defined error category.
224
// user_permission_denied,
225
// user_out_of_memory
228
// class user_error_category_imp : public boost::system::error_category
231
// const std::string & name() const
233
// static std::string s( "test3" );
237
// boost::system::error_code portable_error_code( int ev ) const
241
// case user_success:
242
// return boost::system::error_code(boost::system::errc::success, boost::system::generic_category());
243
// case user_permission_denied:
244
// return boost::system::error_code(boost::system::errc::permission_denied, boost::system::generic_category());
245
// case user_out_of_memory:
246
// return boost::system::error_code(boost::system::errc::not_enough_memory, boost::system::generic_category());
250
// return boost::system::error_code(boost::system::errc::no_posix_equivalent, boost::system::generic_category());
255
// const user_error_category_imp user_error_category_const;
257
// const boost::system::error_category & user_error_category
258
// = user_error_category_const;
260
// template<> inline boost::system::error_code make_error_code(user_err e)
262
// return boost::system::error_code(e, user_error_category);
267
// void check_success(const boost::system::error_code& ec, bool expect)
269
// BOOST_TEST( (ec == boost::system::errc::success) == expect );
270
// if (ec == boost::system::errc::success)
271
// std::cout << "yes... " << (expect ? "ok" : "fail") << '\n';
273
// std::cout << "no... " << (expect ? "fail" : "ok") << '\n';
276
// void check_permission_denied(const boost::system::error_code& ec, bool expect)
278
// BOOST_TEST( (ec == boost::system::errc::permission_denied) == expect );
279
// if (ec == boost::system::errc::permission_denied)
280
// std::cout << "yes... " << (expect ? "ok" : "fail") << '\n';
282
// std::cout << "no... " << (expect ? "fail" : "ok") << '\n';
285
// void check_out_of_memory(const boost::system::error_code& ec, bool expect)
287
// BOOST_TEST( (ec == boost::system::errc::not_enough_memory) == expect );
288
// if (ec == boost::system::errc::not_enough_memory)
289
// std::cout << "yes... " << (expect ? "ok" : "fail") << '\n';
291
// std::cout << "no... " << (expect ? "fail" : "ok") << '\n';
296
// printf("Test3\n");
297
// printf("=====\n");
298
// boost::system::error_code ec;
299
// check_success(ec, true);
300
// check_success(boost::system::errc::success, true);
301
// check_success(boost::system::errc::permission_denied, false);
302
// check_success(boost::system::errc::not_enough_memory, false);
303
// check_success(user_success, true);
304
// check_success(user_permission_denied, false);
305
// check_success(user_out_of_memory, false);
306
// check_permission_denied(ec, false);
307
// check_permission_denied(boost::system::errc::success, false);
308
// check_permission_denied(boost::system::errc::permission_denied, true);
309
// check_permission_denied(boost::system::errc::not_enough_memory, false);
310
// check_permission_denied(user_success, false);
311
// check_permission_denied(user_permission_denied, true);
312
// check_permission_denied(user_out_of_memory, false);
313
// check_out_of_memory(ec, false);
314
// check_out_of_memory(boost::system::errc::success, false);
315
// check_out_of_memory(boost::system::errc::permission_denied, false);
316
// check_out_of_memory(boost::system::errc::not_enough_memory, true);
317
// check_out_of_memory(user_success, false);
318
// check_out_of_memory(user_permission_denied, false);
319
// check_out_of_memory(user_out_of_memory, true);
321
//# ifdef BOOST_WINDOWS_API
322
// check_success(boost::system::windows::success, true);
323
// check_success(boost::system::windows::access_denied, false);
324
// check_success(boost::system::windows::not_enough_memory, false);
325
// check_permission_denied(boost::system::windows::success, false);
326
// check_permission_denied(boost::system::windows::access_denied, true);
327
// check_permission_denied(boost::system::windows::not_enough_memory, false);
328
// check_out_of_memory(boost::system::windows::success, false);
329
// check_out_of_memory(boost::system::windows::access_denied, false);
330
// check_out_of_memory(boost::system::windows::not_enough_memory, true);
336
//} // namespace test3
340
// ------------------------------------------------------------------------ //
342
int main( int, char *[] )
344
boost::system::error_code ec;
348
ec = my_mkdir( "/no-such-file-or-directory/will-not-succeed" );
349
std::cout << "ec.value() is " << ec.value() << '\n';
352
BOOST_TEST( ec == boost::system::errc::no_such_file_or_directory );
353
BOOST_TEST( ec.category() == boost::system::system_category() );
357
ec = my_remove( "/no-such-file-or-directory" );
358
std::cout << "ec.value() is " << ec.value() << '\n';
361
BOOST_TEST( ec == boost::system::errc::no_such_file_or_directory );
362
BOOST_TEST( ec.category() == boost::system::generic_category() );
366
ec = boost::lib3::boo_boo;
367
std::cout << "ec.value() is " << ec.value() << '\n';
370
BOOST_TEST( ec == boost::lib3::boo_boo );
371
BOOST_TEST( ec.value() == boost::lib3::boo_boo );
372
BOOST_TEST( ec.category() == boost::lib3::lib3_error_category );
374
BOOST_TEST( ec == boost::system::errc::io_error );
376
boost::system::error_code ec3( boost::lib3::boo_boo+100,
377
boost::lib3::lib3_error_category );
378
BOOST_TEST( ec3.category() == boost::lib3::lib3_error_category );
379
BOOST_TEST( ec3.default_error_condition().category()
380
== boost::lib3::lib3_error_category );
385
std::cout << "ec.value() is " << ec.value() << '\n';
388
BOOST_TEST( ec == lib4::boo_boo );
389
BOOST_TEST( ec.value() == lib4::boo_boo.value() );
390
BOOST_TEST( ec.category() == lib4::lib4_error_category );
392
BOOST_TEST( ec == boost::system::errc::io_error );
394
boost::system::error_code ec4( lib4::boo_boo.value()+100,
395
lib4::lib4_error_category );
396
BOOST_TEST( ec4.default_error_condition().category()
397
== lib4::lib4_error_category );
403
return ::boost::report_errors();