| 
	1 | 
	
		/* -*- C++ -*-
 
	 | 
	 | 
	2 | 
	
		 *
 
	 | 
	 | 
	3 | 
	
		 * This file is a part of LEMON, a generic C++ optimization library
 
	 | 
	 | 
	4 | 
	
		 *
 
	 | 
	 | 
	5 | 
	
		 * Copyright (C) 2003-2008
 
	 | 
	 | 
	6 | 
	
		 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
	 | 
	 | 
	7 | 
	
		 * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
	 | 
	 | 
	8 | 
	
		 *
 
	 | 
	 | 
	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.
 
	 | 
	 | 
	12 | 
	
		 *
 
	 | 
	 | 
	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
 
	 | 
	 | 
	15 | 
	
		 * purpose.
 
	 | 
	 | 
	16 | 
	
		 *
 
	 | 
	 | 
	17 | 
	
		 */
 
	 | 
	 | 
	18 | 
	
		
 
	 | 
	 | 
	19 | 
	
		#ifndef LEMON_ERROR_H
 
	 | 
	 | 
	20 | 
	
		#define LEMON_ERROR_H
 
	 | 
	 | 
	21 | 
	
		
 
	 | 
	 | 
	22 | 
	
		/// \ingroup exceptions
 
	 | 
	 | 
	23 | 
	
		/// \file
 
	 | 
	 | 
	24 | 
	
		/// \brief Basic exception classes and error handling.
 
	 | 
	 | 
	25 | 
	
		
 
	 | 
	 | 
	26 | 
	
		#include <exception>
 
	 | 
	 | 
	27 | 
	
		#include <string>
 
	 | 
	 | 
	28 | 
	
		#include <sstream>
 
	 | 
	 | 
	29 | 
	
		#include <iostream>
 
	 | 
	 | 
	30 | 
	
		#include <cstdlib>
 
	 | 
	 | 
	31 | 
	
		#include <memory>
 
	 | 
	 | 
	32 | 
	
		
 
	 | 
	 | 
	33 | 
	
		namespace lemon {
	 | 
	 | 
	34 | 
	
		
 
	 | 
	 | 
	35 | 
	
		  /// \addtogroup exceptions
 
	 | 
	 | 
	36 | 
	
		  /// @{
	 | 
	 | 
	37 | 
	
		
 
	 | 
	 | 
	38 | 
	
		  /// \brief Exception safe wrapper class.
 
	 | 
	 | 
	39 | 
	
		  ///
 
	 | 
	 | 
	40 | 
	
		  /// Exception safe wrapper class to implement the members of exceptions.
 
	 | 
	 | 
	41 | 
	
		  template <typename _Type>
 
	 | 
	 | 
	42 | 
	
		  class ExceptionMember {
	 | 
	 | 
	43 | 
	
		  public:
 
	 | 
	 | 
	44 | 
	
		    typedef _Type Type;
 
	 | 
	 | 
	45 | 
	
		
 
	 | 
	 | 
	46 | 
	
		    ExceptionMember() throw() {
	 | 
	 | 
	47 | 
	
		      try {
	 | 
	 | 
	48 | 
	
			ptr.reset(new Type());
 
	 | 
	 | 
	49 | 
	
		      } catch (...) {}
	 | 
	 | 
	50 | 
	
		    }
 
	 | 
	 | 
	51 | 
	
		
 
	 | 
	 | 
	52 | 
	
		    ExceptionMember(const Type& type) throw() {
	 | 
	 | 
	53 | 
	
		      try {
	 | 
	 | 
	54 | 
	
			ptr.reset(new Type());
 
	 | 
	 | 
	55 | 
	
			if (ptr.get() == 0) return;
 
	 | 
	 | 
	56 | 
	
			*ptr = type;
 
	 | 
	 | 
	57 | 
	
		      } catch (...) {}
	 | 
	 | 
	58 | 
	
		    }
 
	 | 
	 | 
	59 | 
	
		
 
	 | 
	 | 
	60 | 
	
		    ExceptionMember(const ExceptionMember& copy) throw() {
	 | 
	 | 
	61 | 
	
		      try {
	 | 
	 | 
	62 | 
	
			if (!copy.valid()) return;
 
	 | 
	 | 
	63 | 
	
			ptr.reset(new Type());
 
	 | 
	 | 
	64 | 
	
			if (ptr.get() == 0) return;
 
	 | 
	 | 
	65 | 
	
			*ptr = copy.get();
 
	 | 
	 | 
	66 | 
	
		      } catch (...) {}
	 | 
	 | 
	67 | 
	
		    }
 
	 | 
	 | 
	68 | 
	
		
 
	 | 
	 | 
	69 | 
	
		    ExceptionMember& operator=(const ExceptionMember& copy) throw() {
	 | 
	 | 
	70 | 
	
		      if (ptr.get() == 0) return;
 
	 | 
	 | 
	71 | 
	
		      try {
	 | 
	 | 
	72 | 
	
			if (!copy.valid()) return;
 
	 | 
	 | 
	73 | 
	
		 	*ptr = copy.get();
 
	 | 
	 | 
	74 | 
	
		      } catch (...) {}
	 | 
	 | 
	75 | 
	
		    }
 
	 | 
	 | 
	76 | 
	
		
 
	 | 
	 | 
	77 | 
	
		    void set(const Type& type) throw() {
	 | 
	 | 
	78 | 
	
		      if (ptr.get() == 0) return;
 
	 | 
	 | 
	79 | 
	
		      try {
	 | 
	 | 
	80 | 
	
			*ptr = type;
 
	 | 
	 | 
	81 | 
	
		      } catch (...) {}
	 | 
	 | 
	82 | 
	
		    }
 
	 | 
	 | 
	83 | 
	
		
 
	 | 
	 | 
	84 | 
	
		    const Type& get() const {
	 | 
	 | 
	85 | 
	
		      return *ptr;
 
	 | 
	 | 
	86 | 
	
		    }
 
	 | 
	 | 
	87 | 
	
		
 
	 | 
	 | 
	88 | 
	
		    bool valid() const throw() {
	 | 
	 | 
	89 | 
	
		      return ptr.get() != 0;
 
	 | 
	 | 
	90 | 
	
		    }
 
	 | 
	 | 
	91 | 
	
		
 
	 | 
	 | 
	92 | 
	
		  private:
 
	 | 
	 | 
	93 | 
	
		    std::auto_ptr<_Type> ptr;
 
	 | 
	 | 
	94 | 
	
		  };
 
	 | 
	 | 
	95 | 
	
		
 
	 | 
	 | 
	96 | 
	
		  /// Exception-safe convenient "error message" class.
 
	 | 
	 | 
	97 | 
	
		
 
	 | 
	 | 
	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).
 
	 | 
	 | 
	101 | 
	
		  class ErrorMessage {
	 | 
	 | 
	102 | 
	
		  protected:
 
	 | 
	 | 
	103 | 
	
		    ///\e
 
	 | 
	 | 
	104 | 
	
		
 
	 | 
	 | 
	105 | 
	
		    ///\todo The good solution is boost::shared_ptr...
 
	 | 
	 | 
	106 | 
	
		    ///
 
	 | 
	 | 
	107 | 
	
		    mutable std::auto_ptr<std::ostringstream> buf;
 
	 | 
	 | 
	108 | 
	
		
 
	 | 
	 | 
	109 | 
	
		    ///\e
 
	 | 
	 | 
	110 | 
	
		    bool init() throw() {
	 | 
	 | 
	111 | 
	
		      try {
	 | 
	 | 
	112 | 
	
			buf.reset(new std::ostringstream);
 
	 | 
	 | 
	113 | 
	
		      }
 
	 | 
	 | 
	114 | 
	
		      catch(...) {
	 | 
	 | 
	115 | 
	
			buf.reset();
 
	 | 
	 | 
	116 | 
	
		      }
 
	 | 
	 | 
	117 | 
	
		      return buf.get();
 
	 | 
	 | 
	118 | 
	
		    }
 
	 | 
	 | 
	119 | 
	
		
 
	 | 
	 | 
	120 | 
	
		  public:
 
	 | 
	 | 
	121 | 
	
		
 
	 | 
	 | 
	122 | 
	
		    ///\e
 
	 | 
	 | 
	123 | 
	
		    ErrorMessage() throw() { init(); }
	 | 
	 | 
	124 | 
	
		
 
	 | 
	 | 
	125 | 
	
		    ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
	 | 
	 | 
	126 | 
	
		
 
	 | 
	 | 
	127 | 
	
		    ///\e
 
	 | 
	 | 
	128 | 
	
		    ErrorMessage(const char *msg) throw() {
	 | 
	 | 
	129 | 
	
		      init();
 
	 | 
	 | 
	130 | 
	
		      *this << msg;
 
	 | 
	 | 
	131 | 
	
		    }
 
	 | 
	 | 
	132 | 
	
		
 
	 | 
	 | 
	133 | 
	
		    ///\e
 
	 | 
	 | 
	134 | 
	
		    ErrorMessage(const std::string &msg) throw() {
	 | 
	 | 
	135 | 
	
		      init();
 
	 | 
	 | 
	136 | 
	
		      *this << msg;
 
	 | 
	 | 
	137 | 
	
		    }
 
	 | 
	 | 
	138 | 
	
		
 
	 | 
	 | 
	139 | 
	
		    ///\e
 
	 | 
	 | 
	140 | 
	
		    template <typename T>
 
	 | 
	 | 
	141 | 
	
		    ErrorMessage& operator<<(const T &t) throw() {
	 | 
	 | 
	142 | 
	
		      if( ! buf.get() ) return *this;
 
	 | 
	 | 
	143 | 
	
		
 
	 | 
	 | 
	144 | 
	
		      try {
	 | 
	 | 
	145 | 
	
			*buf << t;
 
	 | 
	 | 
	146 | 
	
		      }
 
	 | 
	 | 
	147 | 
	
		      catch(...) {
	 | 
	 | 
	148 | 
	
			buf.reset();
 
	 | 
	 | 
	149 | 
	
		      }
 
	 | 
	 | 
	150 | 
	
		      return *this;
 
	 | 
	 | 
	151 | 
	
		    }
 
	 | 
	 | 
	152 | 
	
		
 
	 | 
	 | 
	153 | 
	
		    ///\e
 
	 | 
	 | 
	154 | 
	
		    const char* message() throw() {
	 | 
	 | 
	155 | 
	
		      if( ! buf.get() ) return 0;
 
	 | 
	 | 
	156 | 
	
		
 
	 | 
	 | 
	157 | 
	
		      const char* mes = 0;
 
	 | 
	 | 
	158 | 
	
		      try {
	 | 
	 | 
	159 | 
	
			mes = buf->str().c_str();
 
	 | 
	 | 
	160 | 
	
		      }
 
	 | 
	 | 
	161 | 
	
		      catch(...) {}
	 | 
	 | 
	162 | 
	
		      return mes;
 
	 | 
	 | 
	163 | 
	
		    }
 
	 | 
	 | 
	164 | 
	
		
 
	 | 
	 | 
	165 | 
	
		  };
 
	 | 
	 | 
	166 | 
	
		
 
	 | 
	 | 
	167 | 
	
		  /// Generic exception class.
 
	 | 
	 | 
	168 | 
	
		
 
	 | 
	 | 
	169 | 
	
		  /// Base class for exceptions used in LEMON.
 
	 | 
	 | 
	170 | 
	
		  ///
 
	 | 
	 | 
	171 | 
	
		  class Exception : public std::exception {
	 | 
	 | 
	172 | 
	
		  public:
 
	 | 
	 | 
	173 | 
	
		    ///\e
 
	 | 
	 | 
	174 | 
	
		    Exception() {}
	 | 
	 | 
	175 | 
	
		    ///\e
 
	 | 
	 | 
	176 | 
	
		    virtual ~Exception() throw() {}
	 | 
	 | 
	177 | 
	
		    ///\e
 
	 | 
	 | 
	178 | 
	
		    virtual const char* what() const throw() {
	 | 
	 | 
	179 | 
	
		      return "lemon::Exception";
 
	 | 
	 | 
	180 | 
	
		    }
 
	 | 
	 | 
	181 | 
	
		  };
 
	 | 
	 | 
	182 | 
	
		
 
	 | 
	 | 
	183 | 
	
		  /// One of the two main subclasses of \ref Exception.
 
	 | 
	 | 
	184 | 
	
		
 
	 | 
	 | 
	185 | 
	
		  /// Logic errors represent problems in the internal logic of a program;
 
	 | 
	 | 
	186 | 
	
		  /// in theory, these are preventable, and even detectable before the
 
	 | 
	 | 
	187 | 
	
		  /// program runs (e.g. violations of class invariants).
 
	 | 
	 | 
	188 | 
	
		  ///
 
	 | 
	 | 
	189 | 
	
		  /// A typical example for this is \ref UninitializedParameter.
 
	 | 
	 | 
	190 | 
	
		  class LogicError : public Exception {
	 | 
	 | 
	191 | 
	
		  public:
 
	 | 
	 | 
	192 | 
	
		    virtual const char* what() const throw() {
	 | 
	 | 
	193 | 
	
		      return "lemon::LogicError";
 
	 | 
	 | 
	194 | 
	
		    }
 
	 | 
	 | 
	195 | 
	
		  };
 
	 | 
	 | 
	196 | 
	
		
 
	 | 
	 | 
	197 | 
	
		  /// \ref Exception for uninitialized parameters.
 
	 | 
	 | 
	198 | 
	
		
 
	 | 
	 | 
	199 | 
	
		  /// This error represents problems in the initialization
 
	 | 
	 | 
	200 | 
	
		  /// of the parameters of the algorithms.
 
	 | 
	 | 
	201 | 
	
		  class UninitializedParameter : public LogicError {
	 | 
	 | 
	202 | 
	
		  public:
 
	 | 
	 | 
	203 | 
	
		    virtual const char* what() const throw() {
	 | 
	 | 
	204 | 
	
		      return "lemon::UninitializedParameter";
 
	 | 
	 | 
	205 | 
	
		    }
 
	 | 
	 | 
	206 | 
	
		  };
 
	 | 
	 | 
	207 | 
	
		
 
	 | 
	 | 
	208 | 
	
		
 
	 | 
	 | 
	209 | 
	
		  /// One of the two main subclasses of \ref Exception.
 
	 | 
	 | 
	210 | 
	
		
 
	 | 
	 | 
	211 | 
	
		  /// Runtime errors represent problems outside the scope of a program;
 
	 | 
	 | 
	212 | 
	
		  /// they cannot be easily predicted and can generally only be caught
 
	 | 
	 | 
	213 | 
	
		  /// as the program executes.
 
	 | 
	 | 
	214 | 
	
		  class RuntimeError : public Exception {
	 | 
	 | 
	215 | 
	
		  public:
 
	 | 
	 | 
	216 | 
	
		    virtual const char* what() const throw() {
	 | 
	 | 
	217 | 
	
		      return "lemon::RuntimeError";
 
	 | 
	 | 
	218 | 
	
		    }
 
	 | 
	 | 
	219 | 
	
		  };
 
	 | 
	 | 
	220 | 
	
		
 
	 | 
	 | 
	221 | 
	
		  ///\e
 
	 | 
	 | 
	222 | 
	
		  class RangeError : public RuntimeError {
	 | 
	 | 
	223 | 
	
		  public:
 
	 | 
	 | 
	224 | 
	
		    virtual const char* what() const throw() {
	 | 
	 | 
	225 | 
	
		      return "lemon::RangeError";
 
	 | 
	 | 
	226 | 
	
		    }
 
	 | 
	 | 
	227 | 
	
		  };
 
	 | 
	 | 
	228 | 
	
		
 
	 | 
	 | 
	229 | 
	
		  ///\e
 
	 | 
	 | 
	230 | 
	
		  class IoError : public RuntimeError {
	 | 
	 | 
	231 | 
	
		  public:
 
	 | 
	 | 
	232 | 
	
		    virtual const char* what() const throw() {
	 | 
	 | 
	233 | 
	
		      return "lemon::IoError";
 
	 | 
	 | 
	234 | 
	
		    }
 
	 | 
	 | 
	235 | 
	
		  };
 
	 | 
	 | 
	236 | 
	
		
 
	 | 
	 | 
	237 | 
	
		  ///\e
 
	 | 
	 | 
	238 | 
	
		  class DataFormatError : public IoError {
	 | 
	 | 
	239 | 
	
		  protected:
 
	 | 
	 | 
	240 | 
	
		    ExceptionMember<std::string> _message;
 
	 | 
	 | 
	241 | 
	
		    ExceptionMember<std::string> _file;
 
	 | 
	 | 
	242 | 
	
		    int _line;
 
	 | 
	 | 
	243 | 
	
		
 
	 | 
	 | 
	244 | 
	
		    mutable ExceptionMember<std::string> _message_holder;
 
	 | 
	 | 
	245 | 
	
		  public:
 
	 | 
	 | 
	246 | 
	
		
 
	 | 
	 | 
	247 | 
	
		    DataFormatError(const DataFormatError &dfe) :
 
	 | 
	 | 
	248 | 
	
		      IoError(dfe), _message(dfe._message), _file(dfe._file),
 
	 | 
	 | 
	249 | 
	
		      _line(dfe._line) {}
	 | 
	 | 
	250 | 
	
		
 
	 | 
	 | 
	251 | 
	
		    ///\e
 
	 | 
	 | 
	252 | 
	
		    explicit DataFormatError(const char *the_message)
 
	 | 
	 | 
	253 | 
	
		      : _message(the_message), _line(0) {}
	 | 
	 | 
	254 | 
	
		
 
	 | 
	 | 
	255 | 
	
		    ///\e
 
	 | 
	 | 
	256 | 
	
		    DataFormatError(const std::string &file_name, int line_num,
 
	 | 
	 | 
	257 | 
	
				    const char *the_message)
 
	 | 
	 | 
	258 | 
	
		      : _message(the_message), _line(line_num) { file(file_name); }
	 | 
	 | 
	259 | 
	
		
 
	 | 
	 | 
	260 | 
	
		    ///\e
 
	 | 
	 | 
	261 | 
	
		    void line(int ln) { _line = ln; }
	 | 
	 | 
	262 | 
	
		    ///\e
 
	 | 
	 | 
	263 | 
	
		    void message(const std::string& msg) { _message.set(msg); }
	 | 
	 | 
	264 | 
	
		    ///\e
 
	 | 
	 | 
	265 | 
	
		    void file(const std::string &fl) { _file.set(fl); }
	 | 
	 | 
	266 | 
	
		
 
	 | 
	 | 
	267 | 
	
		    ///\e
 
	 | 
	 | 
	268 | 
	
		    int line() const { return _line; }
	 | 
	 | 
	269 | 
	
		    ///\e
 
	 | 
	 | 
	270 | 
	
		    const char* message() const {
	 | 
	 | 
	271 | 
	
		      if (_message.valid() && !_message.get().empty()) {
	 | 
	 | 
	272 | 
	
			return _message.get().c_str();
 
	 | 
	 | 
	273 | 
	
		      } else {
	 | 
	 | 
	274 | 
	
			return 0;
 
	 | 
	 | 
	275 | 
	
		      }
 
	 | 
	 | 
	276 | 
	
		    }
 
	 | 
	 | 
	277 | 
	
		
 
	 | 
	 | 
	278 | 
	
		    /// \brief Returns the filename.
 
	 | 
	 | 
	279 | 
	
		    ///
 
	 | 
	 | 
	280 | 
	
		    /// Returns \e null if the filename was not specified.
 
	 | 
	 | 
	281 | 
	
		    const char* file() const {
	 | 
	 | 
	282 | 
	
		      if (_file.valid() && !_file.get().empty()) {
	 | 
	 | 
	283 | 
	
			return _file.get().c_str();
 
	 | 
	 | 
	284 | 
	
		      } else {
	 | 
	 | 
	285 | 
	
			return 0;
 
	 | 
	 | 
	286 | 
	
		      }
 
	 | 
	 | 
	287 | 
	
		    }
 
	 | 
	 | 
	288 | 
	
		
 
	 | 
	 | 
	289 | 
	
		    ///\e
 
	 | 
	 | 
	290 | 
	
		    virtual const char* what() const throw() {
	 | 
	 | 
	291 | 
	
		      try {
	 | 
	 | 
	292 | 
	
			std::ostringstream ostr;
 
	 | 
	 | 
	293 | 
	
			ostr << "lemon:DataFormatError" << ": ";
 
	 | 
	 | 
	294 | 
	
			if (message()) ostr << message();
 
	 | 
	 | 
	295 | 
	
			if( file() || line() != 0 ) {
	 | 
	 | 
	296 | 
	
			  ostr << " (";
	 | 
	 | 
	297 | 
	
			  if( file() ) ostr << "in file '" << file() << "'";
 
	 | 
	 | 
	298 | 
	
			  if( file() && line() != 0 ) ostr << " ";
 
	 | 
	 | 
	299 | 
	
			  if( line() != 0 ) ostr << "at line " << line();
 
	 | 
	 | 
	300 | 
	
			  ostr << ")";
 
	 | 
	 | 
	301 | 
	
			}
 
	 | 
	 | 
	302 | 
	
			_message_holder.set(ostr.str());
 
	 | 
	 | 
	303 | 
	
		      }
 
	 | 
	 | 
	304 | 
	
		      catch (...) {}
	 | 
	 | 
	305 | 
	
		      if( _message_holder.valid()) return _message_holder.get().c_str();
 
	 | 
	 | 
	306 | 
	
		      return "lemon:DataFormatError";
 
	 | 
	 | 
	307 | 
	
		    }
 
	 | 
	 | 
	308 | 
	
		
 
	 | 
	 | 
	309 | 
	
		    virtual ~DataFormatError() throw() {}
	 | 
	 | 
	310 | 
	
		  };
 
	 | 
	 | 
	311 | 
	
		
 
	 | 
	 | 
	312 | 
	
		  ///\e
 
	 | 
	 | 
	313 | 
	
		  class FileOpenError : public IoError {
	 | 
	 | 
	314 | 
	
		  protected:
 
	 | 
	 | 
	315 | 
	
		    ExceptionMember<std::string> _file;
 
	 | 
	 | 
	316 | 
	
		
 
	 | 
	 | 
	317 | 
	
		    mutable ExceptionMember<std::string> _message_holder;
 
	 | 
	 | 
	318 | 
	
		  public:
 
	 | 
	 | 
	319 | 
	
		
 
	 | 
	 | 
	320 | 
	
		    FileOpenError(const FileOpenError &foe) :
 
	 | 
	 | 
	321 | 
	
		      IoError(foe), _file(foe._file) {}
	 | 
	 | 
	322 | 
	
		
 
	 | 
	 | 
	323 | 
	
		    ///\e
 
	 | 
	 | 
	324 | 
	
		    explicit FileOpenError(const std::string& fl)
 
	 | 
	 | 
	325 | 
	
		      : _file(fl) {}
	 | 
	 | 
	326 | 
	
		
 
	 | 
	 | 
	327 | 
	
		
 
	 | 
	 | 
	328 | 
	
		    ///\e
 
	 | 
	 | 
	329 | 
	
		    void file(const std::string &fl) { _file.set(fl); }
	 | 
	 | 
	330 | 
	
		
 
	 | 
	 | 
	331 | 
	
		    /// \brief Returns the filename.
 
	 | 
	 | 
	332 | 
	
		    ///
 
	 | 
	 | 
	333 | 
	
		    /// Returns \e null if the filename was not specified.
 
	 | 
	 | 
	334 | 
	
		    const char* file() const {
	 | 
	 | 
	335 | 
	
		      if (_file.valid() && !_file.get().empty()) {
	 | 
	 | 
	336 | 
	
			return _file.get().c_str();
 
	 | 
	 | 
	337 | 
	
		      } else {
	 | 
	 | 
	338 | 
	
			return 0;
 
	 | 
	 | 
	339 | 
	
		      }
 
	 | 
	 | 
	340 | 
	
		    }
 
	 | 
	 | 
	341 | 
	
		
 
	 | 
	 | 
	342 | 
	
		    ///\e
 
	 | 
	 | 
	343 | 
	
		    virtual const char* what() const throw() {
	 | 
	 | 
	344 | 
	
		      try {
	 | 
	 | 
	345 | 
	
			std::ostringstream ostr;
 
	 | 
	 | 
	346 | 
	
			ostr << "lemon::FileOpenError" << ": ";
 
	 | 
	 | 
	347 | 
	
			ostr << "Cannot open file - " << file();
 
	 | 
	 | 
	348 | 
	
			_message_holder.set(ostr.str());
 
	 | 
	 | 
	349 | 
	
		      }
 
	 | 
	 | 
	350 | 
	
		      catch (...) {}
	 | 
	 | 
	351 | 
	
		      if( _message_holder.valid()) return _message_holder.get().c_str();
 
	 | 
	 | 
	352 | 
	
		      return "lemon::FileOpenError";
 
	 | 
	 | 
	353 | 
	
		    }
 
	 | 
	 | 
	354 | 
	
		    virtual ~FileOpenError() throw() {}
	 | 
	 | 
	355 | 
	
		  };
 
	 | 
	 | 
	356 | 
	
		
 
	 | 
	 | 
	357 | 
	
		  class IoParameterError : public IoError {
	 | 
	 | 
	358 | 
	
		  protected:
 
	 | 
	 | 
	359 | 
	
		    ExceptionMember<std::string> _message;
 
	 | 
	 | 
	360 | 
	
		    ExceptionMember<std::string> _file;
 
	 | 
	 | 
	361 | 
	
		
 
	 | 
	 | 
	362 | 
	
		    mutable ExceptionMember<std::string> _message_holder;
 
	 | 
	 | 
	363 | 
	
		  public:
 
	 | 
	 | 
	364 | 
	
		
 
	 | 
	 | 
	365 | 
	
		    IoParameterError(const IoParameterError &ile) :
 
	 | 
	 | 
	366 | 
	
		      IoError(ile), _message(ile._message), _file(ile._file) {}
	 | 
	 | 
	367 | 
	
		
 
	 | 
	 | 
	368 | 
	
		    ///\e
 
	 | 
	 | 
	369 | 
	
		    explicit IoParameterError(const char *the_message)
 
	 | 
	 | 
	370 | 
	
		      : _message(the_message) {}
	 | 
	 | 
	371 | 
	
		
 
	 | 
	 | 
	372 | 
	
		    ///\e
 
	 | 
	 | 
	373 | 
	
		    IoParameterError(const char *file_name, const char *the_message)
 
	 | 
	 | 
	374 | 
	
		      : _message(the_message), _file(file_name) {}
	 | 
	 | 
	375 | 
	
		
 
	 | 
	 | 
	376 | 
	
		     ///\e
 
	 | 
	 | 
	377 | 
	
		    void message(const std::string& msg) { _message.set(msg); }
	 | 
	 | 
	378 | 
	
		    ///\e
 
	 | 
	 | 
	379 | 
	
		    void file(const std::string &fl) { _file.set(fl); }
	 | 
	 | 
	380 | 
	
		
 
	 | 
	 | 
	381 | 
	
		     ///\e
 
	 | 
	 | 
	382 | 
	
		    const char* message() const {
	 | 
	 | 
	383 | 
	
		      if (_message.valid()) {
	 | 
	 | 
	384 | 
	
			return _message.get().c_str();
 
	 | 
	 | 
	385 | 
	
		      } else {
	 | 
	 | 
	386 | 
	
			return 0;
 
	 | 
	 | 
	387 | 
	
		      }
 
	 | 
	 | 
	388 | 
	
		    }
 
	 | 
	 | 
	389 | 
	
		
 
	 | 
	 | 
	390 | 
	
		    /// \brief Returns the filename.
 
	 | 
	 | 
	391 | 
	
		    ///
 
	 | 
	 | 
	392 | 
	
		    /// Returns \c 0 if the filename was not specified.
 
	 | 
	 | 
	393 | 
	
		    const char* file() const {
	 | 
	 | 
	394 | 
	
		      if (_file.valid()) {
	 | 
	 | 
	395 | 
	
			return _file.get().c_str();
 
	 | 
	 | 
	396 | 
	
		      } else {
	 | 
	 | 
	397 | 
	
			return 0;
 
	 | 
	 | 
	398 | 
	
		      }
 
	 | 
	 | 
	399 | 
	
		    }
 
	 | 
	 | 
	400 | 
	
		
 
	 | 
	 | 
	401 | 
	
		    ///\e
 
	 | 
	 | 
	402 | 
	
		    virtual const char* what() const throw() {
	 | 
	 | 
	403 | 
	
		      try {
	 | 
	 | 
	404 | 
	
			std::ostringstream ostr;
 
	 | 
	 | 
	405 | 
	
			if (message()) ostr << message();
 
	 | 
	 | 
	406 | 
	
			if (file()) ostr << "(when reading file '" << file() << "')";
 
	 | 
	 | 
	407 | 
	
			_message_holder.set(ostr.str());
 
	 | 
	 | 
	408 | 
	
		      }
 
	 | 
	 | 
	409 | 
	
		      catch (...) {}
	 | 
	 | 
	410 | 
	
		      if( _message_holder.valid() ) return _message_holder.get().c_str();
 
	 | 
	 | 
	411 | 
	
		      return "lemon:IoParameterError";
 
	 | 
	 | 
	412 | 
	
		    }
 
	 | 
	 | 
	413 | 
	
		    virtual ~IoParameterError() throw() {}
	 | 
	 | 
	414 | 
	
		  };
 
	 | 
	 | 
	415 | 
	
		
 
	 | 
	 | 
	416 | 
	
		
 
	 | 
	 | 
	417 | 
	
		  ///\e
 
	 | 
	 | 
	418 | 
	
		  class AssertionFailedError : public LogicError {
	 | 
	 | 
	419 | 
	
		  protected:
 
	 | 
	 | 
	420 | 
	
		    const char *assertion;
 
	 | 
	 | 
	421 | 
	
		    const char *file;
 
	 | 
	 | 
	422 | 
	
		    int line;
 
	 | 
	 | 
	423 | 
	
		    const char *function;
 
	 | 
	 | 
	424 | 
	
		    const char *message;
 
	 | 
	 | 
	425 | 
	
		
 
	 | 
	 | 
	426 | 
	
		    mutable ExceptionMember<std::string> _message_holder;
 
	 | 
	 | 
	427 | 
	
		  public:
 
	 | 
	 | 
	428 | 
	
		    ///\e
 
	 | 
	 | 
	429 | 
	
		    AssertionFailedError(const char *_file, int _line, const char *func,
 
	 | 
	 | 
	430 | 
	
					 const char *msg, const char *_assertion = 0) :
 
	 | 
	 | 
	431 | 
	
		      assertion(_assertion), file(_file), line(_line), function(func),
 
	 | 
	 | 
	432 | 
	
		      message(msg) {}
	 | 
	 | 
	433 | 
	
		
 
	 | 
	 | 
	434 | 
	
		    ///\e
 
	 | 
	 | 
	435 | 
	
		    const char* get_assertion() const { return assertion; }
	 | 
	 | 
	436 | 
	
		    ///\e
 
	 | 
	 | 
	437 | 
	
		    const char* get_message() const { return message; }
	 | 
	 | 
	438 | 
	
		    ///\e
 
	 | 
	 | 
	439 | 
	
		    const char* get_file() const { return file; }
	 | 
	 | 
	440 | 
	
		    ///\e
 
	 | 
	 | 
	441 | 
	
		    const char* get_function() const { return function; }
	 | 
	 | 
	442 | 
	
		    ///\e
 
	 | 
	 | 
	443 | 
	
		    int get_line() const { return line; }
	 | 
	 | 
	444 | 
	
		
 
	 | 
	 | 
	445 | 
	
		
 
	 | 
	 | 
	446 | 
	
		    virtual const char* what() const throw() {
	 | 
	 | 
	447 | 
	
		      try {
	 | 
	 | 
	448 | 
	
			std::ostringstream ostr;
 
	 | 
	 | 
	449 | 
	
			ostr << file << ":" << line << ": ";
 
	 | 
	 | 
	450 | 
	
			if( function )
 
	 | 
	 | 
	451 | 
	
			  ostr << function << ": ";
 
	 | 
	 | 
	452 | 
	
			ostr << message;
 
	 | 
	 | 
	453 | 
	
			if( assertion )
 
	 | 
	 | 
	454 | 
	
			   ostr << " (assertion '" << assertion << "' failed)";
 
	 | 
	 | 
	455 | 
	
			_message_holder.set(ostr.str());
 
	 | 
	 | 
	456 | 
	
			return ostr.str().c_str();
 
	 | 
	 | 
	457 | 
	
		      }
 
	 | 
	 | 
	458 | 
	
		      catch(...) {}
	 | 
	 | 
	459 | 
	
		      if( _message_holder.valid() ) return _message_holder.get().c_str();
 
	 | 
	 | 
	460 | 
	
		      return "lemon::AssertionFailedError";
 
	 | 
	 | 
	461 | 
	
		    }
 
	 | 
	 | 
	462 | 
	
		   virtual ~AssertionFailedError() throw() {}
	 | 
	 | 
	463 | 
	
		  };
 
	 | 
	 | 
	464 | 
	
		
 
	 | 
	 | 
	465 | 
	
		
 
	 | 
	 | 
	466 | 
	
		  /****************  Macros  ****************/
 
	 | 
	 | 
	467 | 
	
		
 
	 | 
	 | 
	468 | 
	
		
 
	 | 
	 | 
	469 | 
	
		  template <typename Exception>
 
	 | 
	 | 
	470 | 
	
		  inline void assert_fail(const char *file, int line,
 
	 | 
	 | 
	471 | 
	
		                          const char *func,
 
	 | 
	 | 
	472 | 
	
		                          Exception exception,
 
	 | 
	 | 
	473 | 
	
		                          const char *assertion = 0,
 
	 | 
	 | 
	474 | 
	
		                          bool do_abort=true)
 
	 | 
	 | 
	475 | 
	
		  {
	 | 
	 | 
	476 | 
	
		    using namespace std;
 
	 | 
	 | 
	477 | 
	
		    cerr << file << ":" << line << ": ";
 
	 | 
	 | 
	478 | 
	
		    if (func)
 
	 | 
	 | 
	479 | 
	
		      cerr << func << ": ";
 
	 | 
	 | 
	480 | 
	
		    cerr << exception.what();
 
	 | 
	 | 
	481 | 
	
		    if (assertion)
 
	 | 
	 | 
	482 | 
	
		      cerr << " (assertion '" << assertion << "' failed)";
 
	 | 
	 | 
	483 | 
	
		    cerr << endl;
 
	 | 
	 | 
	484 | 
	
		    if (do_abort)
 
	 | 
	 | 
	485 | 
	
		      abort();
 
	 | 
	 | 
	486 | 
	
		  }
 
	 | 
	 | 
	487 | 
	
		
 
	 | 
	 | 
	488 | 
	
		  template <>
 
	 | 
	 | 
	489 | 
	
		  inline void assert_fail<const char *>(const char *file, int line,
 
	 | 
	 | 
	490 | 
	
		                                        const char *func,
 
	 | 
	 | 
	491 | 
	
		                                        const char *message,
 
	 | 
	 | 
	492 | 
	
		                                        const char *assertion,
 
	 | 
	 | 
	493 | 
	
		                                        bool do_abort)
 
	 | 
	 | 
	494 | 
	
		  {
	 | 
	 | 
	495 | 
	
		    using namespace std;
 
	 | 
	 | 
	496 | 
	
		    cerr << file << ":" << line << ": ";
 
	 | 
	 | 
	497 | 
	
		    if (func)
 
	 | 
	 | 
	498 | 
	
		      cerr << func << ": ";
 
	 | 
	 | 
	499 | 
	
		    cerr << message;
 
	 | 
	 | 
	500 | 
	
		    if (assertion)
 
	 | 
	 | 
	501 | 
	
		      cerr << " (assertion '" << assertion << "' failed)";
 
	 | 
	 | 
	502 | 
	
		    cerr << endl;
 
	 | 
	 | 
	503 | 
	
		    if (do_abort)
 
	 | 
	 | 
	504 | 
	
		      abort();
 
	 | 
	 | 
	505 | 
	
		  }
 
	 | 
	 | 
	506 | 
	
		
 
	 | 
	 | 
	507 | 
	
		  template <>
 
	 | 
	 | 
	508 | 
	
		  inline void assert_fail<std::string>(const char *file, int line,
 
	 | 
	 | 
	509 | 
	
		                                       const char *func,
 
	 | 
	 | 
	510 | 
	
		                                       std::string message,
 
	 | 
	 | 
	511 | 
	
		                                       const char *assertion,
 
	 | 
	 | 
	512 | 
	
		                                       bool do_abort)
 
	 | 
	 | 
	513 | 
	
		  {
	 | 
	 | 
	514 | 
	
		    assert_fail(file, line, func, message.c_str(), assertion, do_abort);
 
	 | 
	 | 
	515 | 
	
		  }
 
	 | 
	 | 
	516 | 
	
		
 
	 | 
	 | 
	517 | 
	
		  template <typename Exception>
 
	 | 
	 | 
	518 | 
	
		  inline void assert_fail_failure(const char *file, int line, const char *func,
 
	 | 
	 | 
	519 | 
	
					   Exception exception,
 
	 | 
	 | 
	520 | 
	
					   const char *assertion = 0,
 
	 | 
	 | 
	521 | 
	
					   bool = true)
 
	 | 
	 | 
	522 | 
	
		  {
	 | 
	 | 
	523 | 
	
		    throw AssertionFailedError(file, line, func, exception.what(), assertion);
 
	 | 
	 | 
	524 | 
	
		  }
 
	 | 
	 | 
	525 | 
	
		
 
	 | 
	 | 
	526 | 
	
		  template <>
 
	 | 
	 | 
	527 | 
	
		  inline void assert_fail_failure<const char *>(const char *file, int line,
 
	 | 
	 | 
	528 | 
	
		                                                const char *func,
 
	 | 
	 | 
	529 | 
	
		                                                const char *message,
 
	 | 
	 | 
	530 | 
	
		                                                const char *assertion,
 
	 | 
	 | 
	531 | 
	
		                                                bool)
 
	 | 
	 | 
	532 | 
	
		  {
	 | 
	 | 
	533 | 
	
		    throw AssertionFailedError(file, line, func, message, assertion);
 
	 | 
	 | 
	534 | 
	
		  }
 
	 | 
	 | 
	535 | 
	
		
 
	 | 
	 | 
	536 | 
	
		  template <>
 
	 | 
	 | 
	537 | 
	
		  inline void assert_fail_failure<std::string>(const char *file, int line,
 
	 | 
	 | 
	538 | 
	
		                                               const char *func,
 
	 | 
	 | 
	539 | 
	
		                                               std::string message,
 
	 | 
	 | 
	540 | 
	
		                                               const char *assertion,
 
	 | 
	 | 
	541 | 
	
		                                               bool)
 
	 | 
	 | 
	542 | 
	
		  {
	 | 
	 | 
	543 | 
	
		    assert_fail_failure(file, line, func, message.c_str(), assertion, true);
 
	 | 
	 | 
	544 | 
	
		  }
 
	 | 
	 | 
	545 | 
	
		
 
	 | 
	 | 
	546 | 
	
		  template <typename Exception>
 
	 | 
	 | 
	547 | 
	
		  inline void assert_fail_exception(const char *file, int line, const char *func,
 
	 | 
	 | 
	548 | 
	
					     Exception exception,
 
	 | 
	 | 
	549 | 
	
					     const char *assertion = 0, bool = true)
 
	 | 
	 | 
	550 | 
	
		  {
	 | 
	 | 
	551 | 
	
		    throw exception;
 
	 | 
	 | 
	552 | 
	
		  }
 
	 | 
	 | 
	553 | 
	
		
 
	 | 
	 | 
	554 | 
	
		  template <>
 
	 | 
	 | 
	555 | 
	
		  inline void assert_fail_exception<const char *>(const char *file, int line,
 
	 | 
	 | 
	556 | 
	
							   const char *func,
 
	 | 
	 | 
	557 | 
	
							   const char *message,
 
	 | 
	 | 
	558 | 
	
							   const char *assertion,
 
	 | 
	 | 
	559 | 
	
							   bool)
 
	 | 
	 | 
	560 | 
	
		  {
	 | 
	 | 
	561 | 
	
		    throw AssertionFailedError(file, line, func, message, assertion);
 
	 | 
	 | 
	562 | 
	
		  }
 
	 | 
	 | 
	563 | 
	
		
 
	 | 
	 | 
	564 | 
	
		  template <>
 
	 | 
	 | 
	565 | 
	
		  inline void assert_fail_exception<std::string>(const char *file, int line,
 
	 | 
	 | 
	566 | 
	
		                                                 const char *func,
 
	 | 
	 | 
	567 | 
	
		                                                 std::string message,
 
	 | 
	 | 
	568 | 
	
		                                                 const char *assertion,
 
	 | 
	 | 
	569 | 
	
		                                                 bool)
 
	 | 
	 | 
	570 | 
	
		  {
	 | 
	 | 
	571 | 
	
		    assert_fail_exception(file, line, func, message.c_str(), assertion, true);
 
	 | 
	 | 
	572 | 
	
		  }
 
	 | 
	 | 
	573 | 
	
		
 
	 | 
	 | 
	574 | 
	
		/// @}
 
	 | 
	 | 
	575 | 
	
		
 
	 | 
	 | 
	576 | 
	
		}
 
	 | 
	 | 
	577 | 
	
		#endif // LEMON_ERROR_H
 
	 | 
	 | 
	578 | 
	
		
 
	 | 
	 | 
	579 | 
	
		#undef LEMON_ASSERT
 
	 | 
	 | 
	580 | 
	
		#undef LEMON_FIXME
 
	 | 
	 | 
	581 | 
	
		
 
	 | 
	 | 
	582 | 
	
		#ifdef LEMON_ENABLE_ASSERTS
 
	 | 
	 | 
	583 | 
	
		#  define LEMON_ASSERT_ABORT
 
	 | 
	 | 
	584 | 
	
		#endif
 
	 | 
	 | 
	585 | 
	
		
 
	 | 
	 | 
	586 | 
	
		#ifndef LEMON_ASSERT_DO_ABORT
 
	 | 
	 | 
	587 | 
	
		#  define LEMON_ASSERT_DO_ABORT 1
 
	 | 
	 | 
	588 | 
	
		#endif
 
	 | 
	 | 
	589 | 
	
		
 
	 | 
	 | 
	590 | 
	
		#ifndef LEMON_ASSERT_HANDLER
 
	 | 
	 | 
	591 | 
	
		#  if defined LEMON_ASSERT_EXCEPTION
 
	 | 
	 | 
	592 | 
	
		#    define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
 
	 | 
	 | 
	593 | 
	
		#  elif defined LEMON_ASSERT_FAILURE
 
	 | 
	 | 
	594 | 
	
		#    define LEMON_ASSERT_HANDLER ::lemon::assert_fail_failure
 
	 | 
	 | 
	595 | 
	
		#  elif defined LEMON_ASSERT_ABORT
 
	 | 
	 | 
	596 | 
	
		#    define LEMON_ASSERT_HANDLER ::lemon::assert_fail
 
	 | 
	 | 
	597 | 
	
		#  else
 
	 | 
	 | 
	598 | 
	
		#    define LEMON_DISABLE_ASSERTS
 
	 | 
	 | 
	599 | 
	
		#  endif
 
	 | 
	 | 
	600 | 
	
		#endif
 
	 | 
	 | 
	601 | 
	
		
 
	 | 
	 | 
	602 | 
	
		#ifdef DOXYGEN
 
	 | 
	 | 
	603 | 
	
		
 
	 | 
	 | 
	604 | 
	
		/// \brief Macro for assertions with customizable message
 
	 | 
	 | 
	605 | 
	
		///
 
	 | 
	 | 
	606 | 
	
		/// Macro for assertions with customizable message.
 
	 | 
	 | 
	607 | 
	
		///
 
	 | 
	 | 
	608 | 
	
		/// The assertions are disabled in the default behaviour. You can
 
	 | 
	 | 
	609 | 
	
		/// enable the assertions with the
 
	 | 
	 | 
	610 | 
	
		/// \code
 
	 | 
	 | 
	611 | 
	
		/// #define LEMON_ENABLE_ASSERTS
 
	 | 
	 | 
	612 | 
	
		/// \endcode
 
	 | 
	 | 
	613 | 
	
		/// Then an assert
 
	 | 
	 | 
	614 | 
	
		/// provides a log on the standard error about the assertion and aborts
 
	 | 
	 | 
	615 | 
	
		/// the program if LEMON_ASSERT_DO_ABORT is also defined (otherwise the
 
	 | 
	 | 
	616 | 
	
		/// program keeps on running).
 
	 | 
	 | 
	617 | 
	
		/// By defining LEMON_ASSERT_FAILURE or
 
	 | 
	 | 
	618 | 
	
		/// LEMON_ASSERT_EXCEPTION, you can set other behaviour to the
 
	 | 
	 | 
	619 | 
	
		/// assertions. In case LEMON_ASSERT_FAILURE is given, LEMON_ASSERT
 
	 | 
	 | 
	620 | 
	
		/// will always throw an \c AssertionFailedError exception with
 
	 | 
	 | 
	621 | 
	
		/// the \c msg error message. By using
 
	 | 
	 | 
	622 | 
	
		/// LEMON_ASSERT_EXCEPTION, one can define an arbitrary exception to be thrown.
 
	 | 
	 | 
	623 | 
	
		///
 
	 | 
	 | 
	624 | 
	
		/// The LEMON_ASSERT macro should be called with the \c exp parameter
 
	 | 
	 | 
	625 | 
	
		/// which should be an expression convertible to bool. If the given
 
	 | 
	 | 
	626 | 
	
		/// parameter is false the assertion is raised and one of the assertion
 
	 | 
	 | 
	627 | 
	
		/// behaviour will be activated. The \c msg should be either a const
 
	 | 
	 | 
	628 | 
	
		/// char* message or an exception. When the \c msg is an exception the
 
	 | 
	 | 
	629 | 
	
		/// \ref lemon::Exception::what() "what()" function is called to retrieve and
 
	 | 
	 | 
	630 | 
	
		/// display the error message.
 
	 | 
	 | 
	631 | 
	
		///
 
	 | 
	 | 
	632 | 
	
		/// \todo We should provide some way to reset to the default behaviour,
 
	 | 
	 | 
	633 | 
	
		/// shouldn't we?
 
	 | 
	 | 
	634 | 
	
		///
 
	 | 
	 | 
	635 | 
	
		/// \todo This whole 'assert' business should be placed in a separate
 
	 | 
	 | 
	636 | 
	
		/// include file. The boost assert is not guarded by header sentries
 
	 | 
	 | 
	637 | 
	
		/// which may help to change the behaviour of the assertions in
 
	 | 
	 | 
	638 | 
	
		/// the files.
 
	 | 
	 | 
	639 | 
	
		///
 
	 | 
	 | 
	640 | 
	
		/// \todo __PRETTY_FUNCTION__ should be replaced by something
 
	 | 
	 | 
	641 | 
	
		/// compiler-independent, like BOOST_CURRENT_FUNCTION
 
	 | 
	 | 
	642 | 
	
		
 
	 | 
	 | 
	643 | 
	
		#  define LEMON_ASSERT(exp, msg)                 \
 
	 | 
	 | 
	644 | 
	
		     (static_cast<void> (!!(exp) ? 0 : (         \
 
	 | 
	 | 
	645 | 
	
		       LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
 
	 | 
	 | 
	646 | 
	
		                            __PRETTY_FUNCTION__, \
 
	 | 
	 | 
	647 | 
	
		                            msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))
 
	 | 
	 | 
	648 | 
	
		
 
	 | 
	 | 
	649 | 
	
		#else
 
	 | 
	 | 
	650 | 
	
		#  if defined LEMON_DISABLE_ASSERTS
 
	 | 
	 | 
	651 | 
	
		
 
	 | 
	 | 
	652 | 
	
		#    define LEMON_ASSERT(exp, msg)  (static_cast<void> (0))
 
	 | 
	 | 
	653 | 
	
		
 
	 | 
	 | 
	654 | 
	
		#  else
 
	 | 
	 | 
	655 | 
	
		#    define LEMON_ASSERT(exp, msg)                 \
 
	 | 
	 | 
	656 | 
	
		       (static_cast<void> (!!(exp) ? 0 : (         \
 
	 | 
	 | 
	657 | 
	
		         LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
 
	 | 
	 | 
	658 | 
	
		                              __PRETTY_FUNCTION__, \
 
	 | 
	 | 
	659 | 
	
		                              msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))
 
	 | 
	 | 
	660 | 
	
		#  endif
 
	 | 
	 | 
	661 | 
	
		#endif
 
	 | 
	 | 
	662 | 
	
		
 
	 | 
	 | 
	663 | 
	
		/**
 
	 | 
	 | 
	664 | 
	
		 * \brief Macro for mark not yet implemented features.
 
	 | 
	 | 
	665 | 
	
		 *
 
	 | 
	 | 
	666 | 
	
		 * \todo Is this the right place for this? It should be used only in
 
	 | 
	 | 
	667 | 
	
		 * modules under development.
 
	 | 
	 | 
	668 | 
	
		 *
 
	 | 
	 | 
	669 | 
	
		 * \todo __PRETTY_FUNCTION__ should be replaced by something
 
	 | 
	 | 
	670 | 
	
		 * compiler-independent, like BOOST_CURRENT_FUNCTION
 
	 | 
	 | 
	671 | 
	
		 */
 
	 | 
	 | 
	672 | 
	
		
 
	 | 
	 | 
	673 | 
	
		#define LEMON_FIXME(msg) \
 
	 | 
	 | 
	674 | 
	
		    (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
 
	 | 
	 | 
	675 | 
	
					  "FIXME: " msg)) 
	 |