/** @file
    $Id$
    $Date$
    $Author$
    @copy © Marc Wäckerlin
    @license LGPL, see file COPYING
*/
#ifndef __MRW__STDEXT_HPP__
#define __MRW__STDEXT_HPP__
#include 
#include 
#include 
namespace mrw {
  /** @addtogroup StdExt
   */
  //@{
  /** @defgroup stdextFunction Useful Global Functions
       - @ref getline read exactly one line from a stream
       - @ref ifelse implements a dual ?: operator, like:
              a ? a : b      
      @section stdextGetline Read Line
      
      The global functions mrw::getline read exactly one line from a
      stream, without the need of a buffer. It is therefore guaranteed
      that a whole line is read, regardless of the length of the
      line. The result is returned as std::string.
      @code
      // first syntax returns a string:
      std::string line(mrw::getline(std::cin));
      // second syntax returns the stream:
      while (mrw::getline(std::cin, line))
        std::cout<<"Read: "<?: operation:
             a ? a : b
      If the first parameter is not @c 0, then it is returned,
      otherwise the second parameter is returned. It is equivalent to
      the construct: a ? a : b, but without
      the side effect of duplicated evaluation of parameter
      a.
      Older gcc compiler implemented the non standard extension of
      a?:b, which was exactly the same.
      @param a criteria that is checked and returned if not @c 0
      @param b alternative value to be returned if @c a is @c 0
      @return a ? a : b
      @pre \#include 
      @pre @c T must be convertible to @c bool
  */
  template const T& ifelse(const T& a, const T& b) {
    return a?a:b;
  }
  /** @brief Dual ?: operation:
             a ? a : b
      @copydoc ifelse(const T& a, const T& b) */
  template const T* ifelse(const T* a, const T* b) {
    return a?a:b;
  }
  /** @brief read one line from a stream
      Reads one line from a stream, up to delimiter @c d.
      The delimiter is not appended to the string.
      @param is the stream to read from
      @param d the end of line delimiter
      @return the line read from the stream
      @pre \#include 
  */
  std::string getline(std::istream& is, char d = '\n');
  /** @brief read one line from a stream
      Reads one line from a stream, up to delimiter @c d.
      The delimiter is not appended to the string.
      @param is the stream to read from
      @param s the string to place the line in
      @param d the end of line delimiter
      @return @c s: the line read from the stream
      @return the stream after extraction of line
      @pre \#include 
  */
  std::istream& getline(std::istream& is, std::string& s, char d = '\n');
  //@}
  //@}
}
#endif