diff --git a/eo/src/utils/eoLogger.cpp b/eo/src/utils/eoLogger.cpp index 1330c5323..79813137c 100644 --- a/eo/src/utils/eoLogger.cpp +++ b/eo/src/utils/eoLogger.cpp @@ -40,11 +40,13 @@ Caner Candan #include "eoLogger.h" +/* TODO? +- changer oprateurs +- virer la structure "file" +*/ + void eoLogger::_init() { - _standard_io_streams[&std::cout] = 1; - _standard_io_streams[&std::clog] = 2; - _standard_io_streams[&std::cerr] = 2; // /!\ If you want to add a level dont forget to add it at the header file in the enumerator Levels @@ -55,6 +57,7 @@ void eoLogger::_init() addLevel("logging", eo::logging); addLevel("debug", eo::debug); addLevel("xdebug", eo::xdebug); + } eoLogger::eoLogger() : @@ -66,33 +69,18 @@ eoLogger::eoLogger() : _selectedLevel(eo::progress), _contextLevel(eo::quiet), - _fd(2), - _obuf(_fd, _contextLevel, _selectedLevel) + _obuf(_contextLevel, _selectedLevel) { std::ostream::init(&_obuf); _init(); } -eoLogger::eoLogger(eo::file file) : - std::ostream(NULL), - - _verbose("quiet", "verbose", "Set the verbose level", 'v'), - _printVerboseLevels(false, "print-verbose-levels", "Print verbose levels", 'l'), - _output("", "output", "Redirect a standard output to a file", 'o'), - - _selectedLevel(eo::progress), - _contextLevel(eo::quiet), - _fd(2), - _obuf(_fd, _contextLevel, _selectedLevel) -{ - std::ostream::init(&_obuf); - _init(); - *this << file; -} - eoLogger::~eoLogger() { - if (_fd > 2) { ::close(_fd); } + //redirect(NULL); + if (_obuf._ownedFileStream != NULL) { + delete _obuf._ownedFileStream; + } } void eoLogger::_createParameters( eoParser& parser ) @@ -110,19 +98,21 @@ void eoLogger::_createParameters( eoParser& parser ) //------------------------------------------------------------------ - // we're gonna redirect the log to the given filename if -o is used. + // we redirect the log to the given filename if -o is used. //------------------------------------------------------------------ if ( ! _output.value().empty() ) { - eo::log << eo::file( _output.value() ); + redirect(_output.value()); } + + //------------------------------------------------------------------ //------------------------------------------------------------------ - // we're gonna print the list of levels if -l parameter is used. + // we print the list of levels if -l parameter is used. //------------------------------------------------------------------ if ( _printVerboseLevels.value() ) @@ -163,12 +153,6 @@ eoLogger& operator<<(eoLogger& l, const eo::Levels lvl) return l; } -eoLogger& operator<<(eoLogger& l, eo::file f) -{ - l._fd = ::open(f._f.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644); - return l; -} - eoLogger& operator<<(eoLogger& l, eo::setlevel v) { l._selectedLevel = (v._lvl < 0 ? l._levels[v._v] : v._lvl); @@ -177,26 +161,49 @@ eoLogger& operator<<(eoLogger& l, eo::setlevel v) eoLogger& operator<<(eoLogger& l, std::ostream& os) { - if (l._standard_io_streams.find(&os) != l._standard_io_streams.end()) - { - l._fd = l._standard_io_streams[&os]; - } + l._obuf._outStream = &os; return l; } -eoLogger::outbuf::outbuf(const int& fd, - const eo::Levels& contexlvl, +void eoLogger::redirect(std::ostream& os) +{ + if (_obuf._ownedFileStream != NULL) { + delete _obuf._ownedFileStream; + _obuf._ownedFileStream = NULL; + } + _obuf._outStream = &os; +} + +void eoLogger::redirect(const char * filename) +{ + std::ofstream * os; + if (filename == NULL) { + os = NULL; + } else { + os = new std::ofstream(filename); + } + redirect(*os); + _obuf._ownedFileStream = os; +} + +void eoLogger::redirect(const std::string& filename) +{ + redirect(filename.c_str()); +} + + +eoLogger::outbuf::outbuf(const eo::Levels& contexlvl, const eo::Levels& selectedlvl) - : _fd(fd), _contextLevel(contexlvl), _selectedLevel(selectedlvl) + : _outStream(&std::cout), _ownedFileStream(NULL), _contextLevel(contexlvl), _selectedLevel(selectedlvl) {} int eoLogger::outbuf::overflow(int_type c) { if (_selectedLevel >= _contextLevel) { - if (_fd >= 0 && c != EOF) + if (_outStream && c != EOF) { - ::write(_fd, &c, 1); + (*_outStream) << (char) c; } } return c; @@ -204,10 +211,6 @@ int eoLogger::outbuf::overflow(int_type c) namespace eo { - file::file(const std::string f) - : _f(f) - {} - setlevel::setlevel(const std::string v) : _v(v), _lvl((Levels)-1) {} diff --git a/eo/src/utils/eoLogger.h b/eo/src/utils/eoLogger.h index 9ac1c2115..e655848c7 100644 --- a/eo/src/utils/eoLogger.h +++ b/eo/src/utils/eoLogger.h @@ -91,6 +91,7 @@ Caner Candan #include #include #include +#include #include "eoObject.h" #include "eoParser.h" @@ -113,12 +114,12 @@ namespace eo /** * file * this structure combined with the friend operator<< below is an easy way to select a file as output. - */ + * struct file { explicit file(const std::string f); const std::string _f; - }; + };*/ /** * setlevel @@ -146,7 +147,7 @@ public: eoLogger(); //! overidded ctor in order to instanciate a logger with a file define in parameter - eoLogger(eo::file file); + //eoLogger(eo::file file); //! dtor ~eoLogger(); @@ -189,11 +190,12 @@ private: class outbuf : public std::streambuf { public: - outbuf(const int& fd, const eo::Levels& contexlvl, const eo::Levels& selectedlvl); + outbuf(const eo::Levels& contexlvl, const eo::Levels& selectedlvl); + std::ostream * _outStream; + std::ofstream * _ownedFileStream; protected: virtual int overflow(int_type c); private: - const int& _fd; const eo::Levels& _contextLevel; const eo::Levels& _selectedLevel; }; @@ -211,12 +213,6 @@ public: //! in order to use stream style to define the context verbose level where the following logs will be saved friend eoLogger& operator<<(eoLogger&, const eo::Levels); - /** - * operator<< used there to set a filename through the class file. - */ - //! in order to use stream style to define a file to dump instead the standart output - friend eoLogger& operator<<(eoLogger&, eo::file); - /** * operator<< used there to set a verbose level through the class setlevel. */ @@ -224,12 +220,27 @@ public: friend eoLogger& operator<<(eoLogger&, eo::setlevel); /** + * DEPRECATED: Use instead the redirectTo method * operator<< used there to be able to use std::cout to say that we wish to redirect back the buffer to a standard output. */ //! in order to use stream style to go back to a standart output defined by STL //! and to get retro-compatibility +#warning deprecated friend eoLogger& operator<<(eoLogger&, std::ostream&); + /** + * Redirects the logger to a given output stream. Closing the stream and returning its memory is at the charge of the caller, + * but should not be done while the log is still redirected to it. + */ + void redirect(std::ostream&); + + /** + * Redirects the logger to a file using a filename. + * Closing the file will be done automatically when the logger is redirected again or destroyed. + */ + void redirect(const char * filename); + void redirect(const std::string& filename); + private: friend void make_verbose(eoParser&); @@ -244,13 +255,7 @@ private: eo::Levels _contextLevel; /** - * _fd in storing the file descriptor at this place we can disable easily the buffer in - * changing the value at -1. It is used by operator <<. - */ - int _fd; - - /** - * _obuf std::ostream mandates to use a buffer. _obuf is a outbuf inheriting of std::streambuf. + * _obuf std::ostream mandates to use a buffer. _obuf is a outbuf inheriting from std::streambuf. */ outbuf _obuf; diff --git a/eo/test/t-eoLogger.cpp b/eo/test/t-eoLogger.cpp index 198a88720..a1ea4b60c 100644 --- a/eo/test/t-eoLogger.cpp +++ b/eo/test/t-eoLogger.cpp @@ -3,6 +3,10 @@ //----------------------------------------------------------------------------- #include +//#include +#include +#include +#include //----------------------------------------------------------------------------- @@ -25,8 +29,27 @@ int main(int ac, char** av) eo::log << "We are writing on the default output stream" << std::endl; - eo::log << eo::file("test.txt") << "In FILE" << std::endl; - eo::log << std::cout << "on COUT" << std::endl; + //eo::log << eo::file("test.txt") << "In FILE" << std::endl; + + std::ofstream ofs("logtest.txt"); + //eo::log << ofs << "In FILE" << std::endl; + eo::log.redirect(ofs); + eo::log << "In FILE" << std::endl; + + eo::log.redirect("logtest2.txt"); + eo::log << "In FILE 2" << std::endl; + + std::ostringstream oss; + //eo::log << oss << "In STRINGSTREAM"; + eo::log.redirect(oss); + eo::log << oss << "In STRINGSTREAM"; + + //ofs << oss; + std::cout << "Content of ostringstream: " << oss.str() << std::endl; + + //eo::log << std::cout << "on COUT" << std::endl; + eo::log.redirect(std::cout); + eo::log << "on COUT" << std::endl; eo::log << eo::setlevel("errors"); eo::log << eo::setlevel(eo::errors); diff --git a/mo/src/coolingSchedule/moCoolingSchedule.h b/mo/src/coolingSchedule/moCoolingSchedule.h index 9b65cf1b5..b9863b02f 100644 --- a/mo/src/coolingSchedule/moCoolingSchedule.h +++ b/mo/src/coolingSchedule/moCoolingSchedule.h @@ -55,8 +55,9 @@ public: * update the temperature * @param _temp current temperature to update * @param _acceptedMove true when the move is accepted, false otherwise + * @param _currentSolution the current solution */ - virtual void update(double& _temp, bool _acceptedMove) = 0; + virtual void update(double& _temp, bool _acceptedMove, EOT & _currentSolution) = 0; }; diff --git a/mo/src/coolingSchedule/moDynSpanCoolingSchedule.h b/mo/src/coolingSchedule/moDynSpanCoolingSchedule.h index 34b386312..4e6216ad5 100644 --- a/mo/src/coolingSchedule/moDynSpanCoolingSchedule.h +++ b/mo/src/coolingSchedule/moDynSpanCoolingSchedule.h @@ -80,26 +80,27 @@ public: * update the temperature by a factor * @param _temp current temperature to update * @param _acceptedMove true when the move is accepted, false otherwise + * @param _currentSolution the current solution */ - virtual void update(double& _temp, bool _acceptedMove) { - spanTries++; - - if (_acceptedMove) - spanMove++; - - if (spanTries >= spanTriesMax || spanMove >= spanMoveMax) { - _temp *= alpha; - - if (spanMove == 0) // no move during this span ? - nbSpan++; - else - nbSpan = 0; - - spanTries = 0; - spanMove = 0; - } - } - + virtual void update(double& _temp, bool _acceptedMove, EOT & _currentSolution) { + spanTries++; + + if (_acceptedMove) + spanMove++; + + if (spanTries >= spanTriesMax || spanMove >= spanMoveMax) { + _temp *= alpha; + + if (spanMove == 0) // no move during this span ? + nbSpan++; + else + nbSpan = 0; + + spanTries = 0; + spanMove = 0; + } + } + /** * compare the number of span with no move * @param _temp current temperature diff --git a/mo/src/coolingSchedule/moSimpleCoolingSchedule.h b/mo/src/coolingSchedule/moSimpleCoolingSchedule.h index 5ff4f4920..aa8f1138f 100644 --- a/mo/src/coolingSchedule/moSimpleCoolingSchedule.h +++ b/mo/src/coolingSchedule/moSimpleCoolingSchedule.h @@ -52,7 +52,8 @@ public: * @param _span number of iteration with equal temperature * @param _finalT final temperature, threshold of the stopping criteria */ - moSimpleCoolingSchedule(double _initT, double _alpha, unsigned _span, double _finalT) : initT(_initT), alpha(_alpha), span(_span), finalT(_finalT) {} + moSimpleCoolingSchedule(double _initT, double _alpha, unsigned _span, double _finalT) + : initT(_initT), alpha(_alpha), span(_span), finalT(_finalT) {} /** * Getter on the initial temperature @@ -70,8 +71,9 @@ public: * update the temperature by a factor * @param _temp current temperature to update * @param _acceptedMove true when the move is accepted, false otherwise + * @param _currentSolution the current solution */ - virtual void update(double& _temp, bool _acceptedMove) { + virtual void update(double& _temp, bool _acceptedMove, EOT & _currentSolution) { if (step >= span) { _temp *= alpha; step = 0; diff --git a/mo/src/explorer/moSAexplorer.h b/mo/src/explorer/moSAexplorer.h index 3d9f477ee..37fa57955 100644 --- a/mo/src/explorer/moSAexplorer.h +++ b/mo/src/explorer/moSAexplorer.h @@ -96,7 +96,7 @@ public: * @param _solution unused solution */ virtual void updateParam(EOT & _solution) { - coolingSchedule.update(temperature, this->moveApplied()); + coolingSchedule.update(temperature, this->moveApplied(), _solution); }; /** diff --git a/mo/test/t-moDynSpanCoolingSchedule.cpp b/mo/test/t-moDynSpanCoolingSchedule.cpp index 7bef4ad59..da67008ea 100755 --- a/mo/test/t-moDynSpanCoolingSchedule.cpp +++ b/mo/test/t-moDynSpanCoolingSchedule.cpp @@ -48,38 +48,38 @@ int main() { assert(temperature == 100); //temperature must not changed 2* - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 100); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 100); assert(test(temperature)); //then temperature must be /10 - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 10); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 10); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 10); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 1); std::cout << "\n"; assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); std::cout << "\n"; assert(temperature == 1); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); std::cout << "\n"; assert(temperature == 1); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 0.1); assert(!test(temperature)); diff --git a/mo/test/t-moSimpleCoolingSchedule.cpp b/mo/test/t-moSimpleCoolingSchedule.cpp index b2f8cca17..dc78c6870 100644 --- a/mo/test/t-moSimpleCoolingSchedule.cpp +++ b/mo/test/t-moSimpleCoolingSchedule.cpp @@ -48,38 +48,38 @@ int main() { assert(temperature==100); //temperature must not changed 2* - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==100); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==100); assert(test(temperature)); //then temperature must be /10 - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==10); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==10); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==10); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature == 1); std::cout<< "\n"; assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); std::cout<< "\n"; assert(temperature==1); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); std::cout<< "\n"; assert(temperature==1); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==0.1); assert(!test(temperature));