The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.
The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.
The ResGraphAdaptor is based on this composition.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
22 //! \ingroup exceptions
24 //! \brief Basic exception classes and error handling.
35 /// \addtogroup exceptions
38 /// \brief Exception safe wrapper class.
40 /// Exception safe wrapper class to implement the members of exceptions.
41 template <typename _Type>
42 class ExceptionMember {
46 ExceptionMember() throw () {
48 ptr.reset(new Type());
52 ExceptionMember(const Type& type) throw () {
54 ptr.reset(new Type());
55 if (ptr.get() == 0) return;
60 ExceptionMember(const ExceptionMember& copy) throw() {
62 if (!copy.valid()) return;
63 ptr.reset(new Type());
64 if (ptr.get() == 0) return;
69 ExceptionMember& operator=(const ExceptionMember& copy) {
70 if (ptr.get() == 0) return;
72 if (!copy.valid()) return;
77 void set(const Type& type) {
78 if (ptr.get() == 0) return;
84 const Type& get() const {
89 return ptr.get() != 0;
93 std::auto_ptr<_Type> ptr;
96 /// Exception-safe convenient "error message" class.
98 /// Helper class which provides a convenient ostream-like (operator <<
99 /// based) interface to create a string message. Mostly useful in
100 /// exception classes (therefore the name).
105 ///\todo The good solution is boost::shared_ptr...
108 std::auto_ptr<std::ostringstream> buf;
111 bool init() throw() {
113 buf.reset(new std::ostringstream);
124 ErrorMessage() throw() { init(); }
126 ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
129 ErrorMessage(const char *message) throw() {
135 ErrorMessage(const std::string &message) throw() {
141 template <typename T>
142 ErrorMessage& operator<<(const T &t) throw() {
143 if( ! buf.get() ) return *this;
155 const char* message() throw() {
156 if( ! buf.get() ) return 0;
160 mes = buf->str().c_str();
169 * \brief Generic exception class.
171 * Base class for exceptions used in LEMON.
173 class Exception : public std::exception {
178 virtual ~Exception() throw() {}
181 virtual const char* exceptionName() const {
182 return "lemon::Exception";
186 virtual const char* what() const throw() {
187 return exceptionName();
192 * \brief One of the two main subclasses of \ref Exception.
194 * Logic errors represent problems in the internal logic of a program;
195 * in theory, these are preventable, and even detectable before the
196 * program runs (e.g., violations of class invariants).
198 * A typical example for this is \ref UninitializedParameter.
200 class LogicError : public Exception {
202 virtual const char* exceptionName() const {
203 return "lemon::LogicError";
208 * \brief \ref Exception for uninitialized parameters.
210 * This error represents problems in the initialization
211 * of the parameters of the algorithms.
213 class UninitializedParameter : public LogicError {
215 virtual const char* exceptionName() const {
216 return "lemon::UninitializedParameter";
222 * \brief One of the two main subclasses of \ref Exception.
224 * Runtime errors represent problems outside the scope of a program;
225 * they cannot be easily predicted and can generally only be caught as
226 * the program executes.
228 class RuntimeError : public Exception {
230 virtual const char* exceptionName() const {
231 return "lemon::RuntimeError";
236 class RangeError : public RuntimeError {
238 virtual const char* exceptionName() const {
239 return "lemon::RangeError";
244 class IOError : public RuntimeError {
246 virtual const char* exceptionName() const {
247 return "lemon::IOError";
252 class DataFormatError : public IOError {
254 ExceptionMember<std::string> _message;
255 ExceptionMember<std::string> _file;
258 mutable ExceptionMember<std::string> _message_holder;
261 DataFormatError(const DataFormatError &dfe) :
262 IOError(dfe), _message(dfe._message), _file(dfe._file),
266 explicit DataFormatError(const char *the_message)
267 : _message(the_message), _line(0) {}
270 DataFormatError(const std::string &file_name, int line_num,
271 const char *the_message)
272 : _message(the_message), _line(line_num) { file(file_name); }
275 void line(int line) { _line = line; }
277 void message(const std::string& message) { _message.set(message); }
279 void file(const std::string &file) { _file.set(file); }
282 int line() const { return _line; }
284 const char* message() const {
285 if (_message.valid() && !_message.get().empty()) {
286 return _message.get().c_str();
292 /// \brief Returns the filename.
294 /// Returns \e null if the filename was not specified.
295 const char* file() const {
296 if (_file.valid() && !_file.get().empty()) {
297 return _file.get().c_str();
304 virtual const char* what() const throw() {
306 std::ostringstream ostr;
307 ostr << exceptionName() << ": ";
308 if (message()) ostr << message();
309 if( file() || line() != 0 ) {
311 if( file() ) ostr << "in file '" << file() << "'";
312 if( file() && line() != 0 ) ostr << " ";
313 if( line() != 0 ) ostr << "at line " << line();
316 _message_holder.set(ostr.str());
319 if( _message_holder.valid()) return _message_holder.get().c_str();
320 return exceptionName();
323 virtual const char* exceptionName() const {
324 return "lemon::DataFormatError";
327 virtual ~DataFormatError() throw() {}
331 class FileOpenError : public IOError {
333 ExceptionMember<std::string> _file;
335 mutable ExceptionMember<std::string> _message_holder;
338 FileOpenError(const FileOpenError &foe) :
339 IOError(foe), _file(foe._file) {}
342 explicit FileOpenError(const std::string& file)
347 void file(const std::string &file) { _file.set(file); }
349 /// \brief Returns the filename.
351 /// Returns \e null if the filename was not specified.
352 const char* file() const {
353 if (_file.valid() && !_file.get().empty()) {
354 return _file.get().c_str();
361 virtual const char* what() const throw() {
363 std::ostringstream ostr;
364 ostr << exceptionName() << ": ";
365 ostr << "Cannot open file - " << file();
366 _message_holder.set(ostr.str());
369 if( _message_holder.valid()) return _message_holder.get().c_str();
370 return exceptionName();
373 virtual const char* exceptionName() const {
374 return "lemon::FileOpenError";
377 virtual ~FileOpenError() throw() {}
380 class IOParameterError : public IOError {
382 ExceptionMember<std::string> _message;
383 ExceptionMember<std::string> _file;
385 mutable ExceptionMember<std::string> _message_holder;
388 IOParameterError(const IOParameterError &ile) :
389 IOError(ile), _message(ile._message), _file(ile._file) {}
392 explicit IOParameterError(const char *the_message)
393 : _message(the_message) {}
396 IOParameterError(const char *file_name, const char *the_message)
397 : _message(the_message), _file(file_name) {}
400 void message(const std::string& message) { _message.set(message); }
402 void file(const std::string &file) { _file.set(file); }
405 const char* message() const {
406 if (_message.valid()) {
407 return _message.get().c_str();
413 /// \brief Returns the filename.
415 /// Returns \e null if the filename was not specified.
416 const char* file() const {
418 return _file.get().c_str();
425 virtual const char* what() const throw() {
427 std::ostringstream ostr;
428 if (message()) ostr << message();
429 if (file()) ostr << "(when reading file '" << file() << "')";
430 _message_holder.set(ostr.str());
433 if( _message_holder.valid() ) return _message_holder.get().c_str();
434 return exceptionName();
437 virtual const char* exceptionName() const {
438 return "lemon::IOParameterError";
441 virtual ~IOParameterError() throw() {}
446 class AssertionFailedError : public LogicError {
448 const char *assertion;
451 const char *function;
454 mutable ExceptionMember<std::string> _message_holder;
457 AssertionFailedError(const char *_file, int _line, const char *func,
458 const char *msg, const char *_assertion = 0) :
459 assertion(_assertion), file(_file), line(_line), function(func),
463 const char* get_assertion() const { return assertion; }
465 const char* get_message() const { return message; }
467 const char* get_file() const { return file; }
469 const char* get_function() const { return function; }
471 int get_line() const { return line; }
474 virtual const char* what() const throw() {
476 std::ostringstream ostr;
477 ostr << file << ":" << line << ": ";
479 ostr << function << ": ";
482 ostr << " (assertion '" << assertion << "' failed)";
483 _message_holder.set(ostr.str());
484 return ostr.str().c_str();
487 if( _message_holder.valid() ) return _message_holder.get().c_str();
488 return exceptionName();
491 virtual const char* exceptionName() const {
492 return "lemon::AssertionFailedError";
495 virtual ~AssertionFailedError() throw() {}
499 /**************** Macros ****************/
502 template <typename Exception>
503 inline void assert_fail(const char *file, int line, const char *func,
504 Exception exception, const char *assertion = 0,
508 cerr << file << ":" << line << ": ";
510 cerr << func << ": ";
511 cerr << exception.what();
513 cerr << " (assertion '" << assertion << "' failed)";
520 inline void assert_fail<const char *>(const char *file, int line, const char *func,
522 const char *assertion,
526 cerr << file << ":" << line << ": ";
528 cerr << func << ": ";
531 cerr << " (assertion '" << assertion << "' failed)";
537 template <typename Exception>
538 inline void assert_fail_failure(const char *file, int line, const char *func,
540 const char *assertion = 0,
543 throw AssertionFailedError(file, line, func, exception.what(), assertion);
547 inline void assert_fail_failure<const char *>(const char *file, int line,
550 const char *assertion,
553 throw AssertionFailedError(file, line, func, message, assertion);
556 template <typename Exception>
557 inline void assert_fail_exception(const char *file, int line, const char *func,
559 const char *assertion = 0, bool = true)
565 inline void assert_fail_exception<const char *>(const char *file, int line,
568 const char *assertion,
571 throw AssertionFailedError(file, line, func, message, assertion);
577 #endif // LEMON_ERROR_H
582 #ifndef LEMON_ASSERT_ABORT
583 # define LEMON_ASSERT_ABORT 1
586 #ifndef LEMON_ASSERT_HANDLER
587 # if defined LEMON_ASSERT_EXCEPTION
588 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
589 # elif defined LEMON_ASSERT_FAILURE
590 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_failure
592 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail
596 #if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
598 # define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
603 * \brief Macro for assertions with customizable message
605 * Macro for assertions with customizable message.
607 * The behaviour can be customized with LEMON_ASSERT_HANDLER,
608 * LEMON_ASSERT_EXCEPTION and LEMON_ASSERT_ABORT defines. Asserts can be
609 * disabled by defining either NDEBUG or LEMON_DISABLE_ASSERTS macros.
611 * \todo We should provide some way to reset to the default behaviour,
614 * \todo This whole 'assert' business should be placed in a separate
615 * include file. The boost assert is not guarded by header sentries
616 * which may help to change the behaviour of the assertions in
619 * \todo __PRETTY_FUNCTION__ should be replaced by something
620 * compiler-independent, like BOOST_CURRENT_FUNCTION
623 # define LEMON_ASSERT(exp, msg) \
624 (static_cast<void> (!!(exp) ? 0 : ( \
625 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
626 __PRETTY_FUNCTION__, \
627 msg, #exp, LEMON_ASSERT_ABORT), 0)))
629 #endif // NDEBUG || LEMON_DISABLE_ASSERTS
632 * \brief Macro for mark not yet implemented features.
634 * \todo Is this the right place for this? It should be used only in
635 * modules under development.
637 * \todo __PRETTY_FUNCTION__ should be replaced by something
638 * compiler-independent, like BOOST_CURRENT_FUNCTION
641 # define LEMON_FIXME(msg) \
642 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \