yat/utility/utility.h

Code
Comments
Other
Rev Date Author Line
680 11 Oct 06 jari 1 #ifndef _theplu_yat_utility_utility_
2867 12 Nov 12 peter 2 #define _theplu_yat_utility_utility_
616 31 Aug 06 jari 3
327 30 May 05 jari 4 // $Id$
327 30 May 05 jari 5
570 05 Apr 06 jari 6 /*
2119 12 Dec 09 peter 7   Copyright (C) 2005 Jari Häkkinen, Peter Johansson, Markus Ringnér
2119 12 Dec 09 peter 8   Copyright (C) 2006 Jari Häkkinen
4359 23 Aug 23 peter 9   Copyright (C) 2007 Peter Johansson
4359 23 Aug 23 peter 10   Copyright (C) 2008 Jari Häkkinen, Peter Johansson
4359 23 Aug 23 peter 11   Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2023 Peter Johansson
570 05 Apr 06 jari 12
1437 25 Aug 08 peter 13   This file is part of the yat library, http://dev.thep.lu.se/yat
570 05 Apr 06 jari 14
675 10 Oct 06 jari 15   The yat library is free software; you can redistribute it and/or
675 10 Oct 06 jari 16   modify it under the terms of the GNU General Public License as
1486 09 Sep 08 jari 17   published by the Free Software Foundation; either version 3 of the
675 10 Oct 06 jari 18   License, or (at your option) any later version.
570 05 Apr 06 jari 19
675 10 Oct 06 jari 20   The yat library is distributed in the hope that it will be useful,
675 10 Oct 06 jari 21   but WITHOUT ANY WARRANTY; without even the implied warranty of
675 10 Oct 06 jari 22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
570 05 Apr 06 jari 23   General Public License for more details.
570 05 Apr 06 jari 24
570 05 Apr 06 jari 25   You should have received a copy of the GNU General Public License
1487 10 Sep 08 jari 26   along with yat. If not, see <http://www.gnu.org/licenses/>.
570 05 Apr 06 jari 27 */
570 05 Apr 06 jari 28
327 30 May 05 jari 29 ///
1401 07 Aug 08 peter 30 /// \file yat/utility/utility.h
327 30 May 05 jari 31 ///
680 11 Oct 06 jari 32 /// @brief Some useful functions are placed here
327 30 May 05 jari 33 ///
327 30 May 05 jari 34
3640 03 May 17 peter 35 #include "config_public.h"
3640 03 May 17 peter 36
3287 12 Jul 14 peter 37 #include "concept_check.h"
1500 15 Sep 08 peter 38 #include "deprecate.h"
1928 30 Apr 09 peter 39 #include "Exception.h"
3287 12 Jul 14 peter 40 #include "iterator_traits.h"
3287 12 Jul 14 peter 41 #include "WeightIterator.h"
2818 29 Aug 12 peter 42 #include "yat_assert.h"
1500 15 Sep 08 peter 43
3287 12 Jul 14 peter 44 #include <boost/iterator/iterator_concepts.hpp>
3287 12 Jul 14 peter 45 #include <boost/concept_check.hpp>
3287 12 Jul 14 peter 46
2673 03 Dec 11 peter 47 #include <algorithm>
2673 03 Dec 11 peter 48 #include <cctype>
1789 10 Feb 09 peter 49 #include <cmath>
3475 08 Mar 16 peter 50 #include <cstdlib>
3902 05 May 20 peter 51 #include <cstring>
2673 03 Dec 11 peter 52 #include <functional>
1437 25 Aug 08 peter 53 #include <limits>
2673 03 Dec 11 peter 54 #include <locale>
1922 24 Apr 09 peter 55 #include <istream>
3730 10 Apr 18 peter 56 #include <iostream>
3287 12 Jul 14 peter 57 #include <numeric>
327 30 May 05 jari 58 #include <string>
1005 24 Jan 08 peter 59 #include <stdexcept>
1005 24 Jan 08 peter 60 #include <sstream>
616 31 Aug 06 jari 61 #include <utility>
616 31 Aug 06 jari 62 #include <vector>
327 30 May 05 jari 63
327 30 May 05 jari 64 namespace theplu {
680 11 Oct 06 jari 65 namespace yat {
327 30 May 05 jari 66 namespace utility {
327 30 May 05 jari 67
1789 10 Feb 09 peter 68   /**
2907 15 Dec 12 peter 69      Same as posix C function with same name but works on \c
2907 15 Dec 12 peter 70      std::string rather than \c char*.
2907 15 Dec 12 peter 71
2907 15 Dec 12 peter 72      \see http://linux.die.net/man/3/basename
2907 15 Dec 12 peter 73
2892 09 Dec 12 peter 74      \return everything after last '/'
2906 15 Dec 12 peter 75
2906 15 Dec 12 peter 76      \since New in yat 0.10
2892 09 Dec 12 peter 77    */
2892 09 Dec 12 peter 78   std::string basename(const std::string& fn);
2892 09 Dec 12 peter 79
2892 09 Dec 12 peter 80   /**
3902 05 May 20 peter 81      Read data from \a is into variable \a x. Data has typically been
3902 05 May 20 peter 82      written with binary_write(std::ostream& os, T).
3902 05 May 20 peter 83
3902 05 May 20 peter 84      \c T is expected to be a native numerical type.
3902 05 May 20 peter 85
3902 05 May 20 peter 86      \return \a is
3902 05 May 20 peter 87
3902 05 May 20 peter 88      \since New in yat 0.18
3902 05 May 20 peter 89    */
3902 05 May 20 peter 90   template<typename T>
3902 05 May 20 peter 91   std::istream& binary_read(std::istream& is, T& x)
3902 05 May 20 peter 92   {
3902 05 May 20 peter 93     const unsigned char type_size=sizeof(T);
3902 05 May 20 peter 94     YAT_ASSERT(type_size <= 16);
3902 05 May 20 peter 95     char buffer[16];
3902 05 May 20 peter 96     is.read(buffer, type_size);
3902 05 May 20 peter 97     memcpy(&x, buffer, type_size);
3902 05 May 20 peter 98     return is;
3902 05 May 20 peter 99   }
3902 05 May 20 peter 100
3902 05 May 20 peter 101
3902 05 May 20 peter 102   /**
3902 05 May 20 peter 103      Write value of \a x into ostream \a os in binary format. Since
3902 05 May 20 peter 104      the data is written in the native binary format, it may not be
3902 05 May 20 peter 105      portable between different architectures.
3902 05 May 20 peter 106
3902 05 May 20 peter 107      \c T is expected to be a native numerical type.
3902 05 May 20 peter 108
3902 05 May 20 peter 109      \see binary_read(std::istream&, T&)
3902 05 May 20 peter 110
3902 05 May 20 peter 111      \since New in yat 0.18
3902 05 May 20 peter 112    */
3902 05 May 20 peter 113   template<typename T>
3902 05 May 20 peter 114   void binary_write(std::ostream& os, T x)
3902 05 May 20 peter 115   {
3902 05 May 20 peter 116     const unsigned char type_size=sizeof(T);
3902 05 May 20 peter 117     YAT_ASSERT(type_size <= 16);
3902 05 May 20 peter 118     char buffer[16];
3902 05 May 20 peter 119     memcpy(buffer, &x, type_size);
3902 05 May 20 peter 120     os.write(buffer, type_size);
3902 05 May 20 peter 121   }
3902 05 May 20 peter 122
3902 05 May 20 peter 123   /**
1789 10 Feb 09 peter 124      For each element in resulting range assign it to 0.0 if
1789 10 Feb 09 peter 125      corresponding element in input range is NaN else assign it to
1789 10 Feb 09 peter 126      1.0.
327 30 May 05 jari 127
1807 18 Feb 09 peter 128      \return true if there is at least one NaN in input range
1807 18 Feb 09 peter 129      [first, last).
1807 18 Feb 09 peter 130
3507 19 Jul 16 peter 131      Type Requirements:
3507 19 Jul 16 peter 132      - \c InputIterator is \single_pass_iterator
3507 19 Jul 16 peter 133      - \c InputIterator is \readable_iterator
3507 19 Jul 16 peter 134      - \c std::isnan(*InputIterator) is a valid expression (e.g. \c
3507 19 Jul 16 peter 135        float, \c double, and \c long \c double )
3507 19 Jul 16 peter 136      - \c OutputIterator is \incrementable_iterator
3507 19 Jul 16 peter 137      - \c OutputIterator is \writable_iterator
3507 19 Jul 16 peter 138      - \c float is convertible to \c OutputIterator value type
3507 19 Jul 16 peter 139
1789 10 Feb 09 peter 140      \since New in yat 0.5
1807 18 Feb 09 peter 141   */
1807 18 Feb 09 peter 142   template<typename InputIterator, typename OutputIterator>
2907 15 Dec 12 peter 143   bool binary_weight(InputIterator first, InputIterator last,
1807 18 Feb 09 peter 144                      OutputIterator result);
1789 10 Feb 09 peter 145
2426 13 Feb 11 peter 146   /**
2907 15 Dec 12 peter 147      Same as C function \c chdir but throws on failure (instead of
2907 15 Dec 12 peter 148      retrning non-zero).
2906 15 Dec 12 peter 149
2907 15 Dec 12 peter 150      \throw runtime_error if underlying chdir returns non-zero
2906 15 Dec 12 peter 151
2907 15 Dec 12 peter 152      \see http://linux.die.net/man/3/chdir
2907 15 Dec 12 peter 153
2906 15 Dec 12 peter 154      \since New in yat 0.10
2906 15 Dec 12 peter 155    */
2906 15 Dec 12 peter 156   void chdir(const std::string& dir);
2906 15 Dec 12 peter 157
2906 15 Dec 12 peter 158   /**
2907 15 Dec 12 peter 159      same as C function \c chmod but throws on failure (instead of
2907 15 Dec 12 peter 160      returning non-zero).
2907 15 Dec 12 peter 161
2907 15 Dec 12 peter 162      \see http://linux.die.net/man/3/chmod
2907 15 Dec 12 peter 163
2906 15 Dec 12 peter 164      \since New in yat 0.10
2906 15 Dec 12 peter 165    */
2906 15 Dec 12 peter 166   void chmod(const std::string& filename, mode_t mode);
2906 15 Dec 12 peter 167
2906 15 Dec 12 peter 168   /**
4102 22 Sep 21 peter 169      \return true if string \a str contains \a s
4102 22 Sep 21 peter 170
4102 22 Sep 21 peter 171      \see https://en.cppreference.com/w/cpp/string/basic_string/comtains
4102 22 Sep 21 peter 172
4102 22 Sep 21 peter 173      \since New in yat 0.20
4102 22 Sep 21 peter 174    */
4102 22 Sep 21 peter 175   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 176   bool contains(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 177                 const std::basic_string<charT, Traits, Allocator>& substr);
4102 22 Sep 21 peter 178
4102 22 Sep 21 peter 179   /// since New in yat 0.20
4102 22 Sep 21 peter 180   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 181   bool contains(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 182                 charT substr);
4102 22 Sep 21 peter 183
4102 22 Sep 21 peter 184   /// since New in yat 0.20
4102 22 Sep 21 peter 185   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 186   bool contains(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 187                 const charT* substr);
4102 22 Sep 21 peter 188
4102 22 Sep 21 peter 189
4102 22 Sep 21 peter 190   /**
2426 13 Feb 11 peter 191      \brief convert T to a string
1789 10 Feb 09 peter 192
3749 12 Oct 18 peter 193      \c T is supposed to be a numerical type.
2426 13 Feb 11 peter 194
3749 12 Oct 18 peter 195      \see
3749 12 Oct 18 peter 196      <a href="http://www.cplusplus.com/reference/string/to_string/">std::to_string</a>
3749 12 Oct 18 peter 197      in C++11
3749 12 Oct 18 peter 198
2426 13 Feb 11 peter 199      \since new in yat 0.8
2426 13 Feb 11 peter 200    */
2426 13 Feb 11 peter 201   template<typename T>
2426 13 Feb 11 peter 202   std::string convert(T input);
2426 13 Feb 11 peter 203
1005 24 Jan 08 peter 204   /**
1005 24 Jan 08 peter 205      \brief convert string to (numerical) type
1005 24 Jan 08 peter 206
1005 24 Jan 08 peter 207      \throw runtime_error if conversion fails
1005 24 Jan 08 peter 208    */
1005 24 Jan 08 peter 209   template<typename T>
1057 07 Feb 08 peter 210   T convert(const std::string& s);
1005 24 Jan 08 peter 211
1312 19 May 08 peter 212   /**
3597 22 Jan 17 peter 213      \brief try to convert
3597 22 Jan 17 peter 214
3597 22 Jan 17 peter 215      \see is<T>
3597 22 Jan 17 peter 216      \see convert<T>
3597 22 Jan 17 peter 217
3597 22 Jan 17 peter 218      \return true if conversion was successful
3597 22 Jan 17 peter 219
3597 22 Jan 17 peter 220      \since new in yat 0.15
3597 22 Jan 17 peter 221    */
3597 22 Jan 17 peter 222   template<typename T>
3597 22 Jan 17 peter 223   bool convert_try(const std::string& s, T& t);
3597 22 Jan 17 peter 224
3597 22 Jan 17 peter 225   /**
2906 15 Dec 12 peter 226      @brief Copy file \a source to \a target.
2906 15 Dec 12 peter 227
2907 15 Dec 12 peter 228      @throw runtime_error if read error of \a source or write error
2907 15 Dec 12 peter 229      for \a target is encountered.
2906 15 Dec 12 peter 230   */
2906 15 Dec 12 peter 231   void copy_file(const std::string& source, const std::string& target);
2906 15 Dec 12 peter 232
3475 08 Mar 16 peter 233
2906 15 Dec 12 peter 234   /**
2907 15 Dec 12 peter 235      Same as posix C function with same name but works on \c
2907 15 Dec 12 peter 236      std::string rather than \c char*.
2907 15 Dec 12 peter 237
2907 15 Dec 12 peter 238      \see http://linux.die.net/man/3/dirname
2907 15 Dec 12 peter 239
2892 09 Dec 12 peter 240      \return everything prior last '/'.
2906 15 Dec 12 peter 241
2906 15 Dec 12 peter 242      \since New in yat 0.10
2892 09 Dec 12 peter 243    */
2892 09 Dec 12 peter 244   std::string dirname(const std::string& fn);
2892 09 Dec 12 peter 245
2892 09 Dec 12 peter 246   /**
4102 22 Sep 21 peter 247      \return true if string \a str ends with \a suffix
4102 22 Sep 21 peter 248
4102 22 Sep 21 peter 249      \see https://en.cppreference.com/w/cpp/string/basic_string/ends_with
4102 22 Sep 21 peter 250
4102 22 Sep 21 peter 251      \since New in yat 0.20
4102 22 Sep 21 peter 252    */
4102 22 Sep 21 peter 253   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 254   bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 255                  const std::basic_string<charT, Traits, Allocator>& suffix);
4102 22 Sep 21 peter 256
4102 22 Sep 21 peter 257   /// since New in yat 0.20
4102 22 Sep 21 peter 258   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 259   bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 260                  charT suffix);
4102 22 Sep 21 peter 261
4102 22 Sep 21 peter 262   /// since New in yat 0.20
4102 22 Sep 21 peter 263   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 264   bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 265                  const charT* suffix);
4102 22 Sep 21 peter 266
4102 22 Sep 21 peter 267   /**
2906 15 Dec 12 peter 268      \return true if \a str matches \a pattern
2906 15 Dec 12 peter 269
2908 15 Dec 12 peter 270      \see http://linux.die.net/man/3/fnmatch
2906 15 Dec 12 peter 271
2908 15 Dec 12 peter 272      \throw runtime_error if returned value from underlying fnmatch is
2908 15 Dec 12 peter 273      neither zero nor \c FNM_NOMATCH.
2908 15 Dec 12 peter 274
2906 15 Dec 12 peter 275      \since New in yat 0.10
2906 15 Dec 12 peter 276   */
2907 15 Dec 12 peter 277   bool fnmatch(const std::string& pattern, const std::string& str,
2907 15 Dec 12 peter 278                int flags=0);
2906 15 Dec 12 peter 279
2906 15 Dec 12 peter 280   /**
3803 12 May 19 peter 281      \brief current directory
3803 12 May 19 peter 282
3803 12 May 19 peter 283      \see ​https://linux.die.net/man/3/getcwd
3803 12 May 19 peter 284
3803 12 May 19 peter 285      \since New in yat 0.17
3803 12 May 19 peter 286    */
3803 12 May 19 peter 287   std::string getcwd(void);
3803 12 May 19 peter 288
3803 12 May 19 peter 289   /**
3963 06 Aug 20 peter 290      Function can be used as argument to \c gsl_set_error_handler, so
3963 06 Aug 20 peter 291      it is called when by GSL when an error is detected. This will
3963 06 Aug 20 peter 292      result in a GSL_error is thrown.
3963 06 Aug 20 peter 293
3963 06 Aug 20 peter 294      \see https://www.gnu.org/software/gsl/doc/html/err.html
3963 06 Aug 20 peter 295
3963 06 Aug 20 peter 296      \since New in yat 0.18
3963 06 Aug 20 peter 297    */
3963 06 Aug 20 peter 298   void gsl_error_handler(const char* reason, const char* file,
3963 06 Aug 20 peter 299                          int line, int gsl_errno);
3963 06 Aug 20 peter 300
3963 06 Aug 20 peter 301   /**
2581 05 Oct 11 peter 302      \brief check if string is convertible to (numerical) type \c T
1339 06 Jun 08 peter 303
1339 06 Jun 08 peter 304      \since New in yat 0.5
1312 19 May 08 peter 305    */
1312 19 May 08 peter 306   template<typename T>
1312 19 May 08 peter 307   bool is(const std::string& s);
1312 19 May 08 peter 308
327 30 May 05 jari 309   ///
435 14 Dec 05 markus 310   /// @return true if string is a double
327 30 May 05 jari 311   ///
1338 06 Jun 08 peter 312   /// \deprecated Provided for backward compatibility with the 0.4
1338 06 Jun 08 peter 313   /// API. Use is<double>(const std::string&)
1312 19 May 08 peter 314   ///
1500 15 Sep 08 peter 315   bool is_double(const std::string&) YAT_DEPRECATE;
435 14 Dec 05 markus 316
917 30 Sep 07 peter 317   /**
2117 07 Dec 09 peter 318      This function takes the first word (separated by whitespace) in
2117 07 Dec 09 peter 319      \a s, replaces all upper case with lower case, and compares it
2117 07 Dec 09 peter 320      with \a other.
2117 07 Dec 09 peter 321
2117 07 Dec 09 peter 322      \return true if processed \a s is equal to \a other. It returns
2117 07 Dec 09 peter 323      false otherwise or if \a s contains more than one word.
917 30 Sep 07 peter 324   */
917 30 Sep 07 peter 325   bool is_equal(std::string s, std::string other);
435 14 Dec 05 markus 326
327 30 May 05 jari 327   ///
435 14 Dec 05 markus 328   /// @return true if string is a float
435 14 Dec 05 markus 329   ///
1338 06 Jun 08 peter 330   /// \deprecated Provided for backward compatibility with the 0.4
1338 06 Jun 08 peter 331   /// API. Use is<float>(const std::string&)
1312 19 May 08 peter 332   ///
1500 15 Sep 08 peter 333   bool is_float(const std::string&) YAT_DEPRECATE;
327 30 May 05 jari 334
327 30 May 05 jari 335   ///
435 14 Dec 05 markus 336   /// @return true if string is an int
327 30 May 05 jari 337   ///
1338 06 Jun 08 peter 338   /// \deprecated Provided for backward compatibility with the 0.4
1338 06 Jun 08 peter 339   /// API. Use is<int>(const std::string&)
1312 19 May 08 peter 340   ///
1500 15 Sep 08 peter 341   bool is_int(const std::string&) YAT_DEPRECATE;
327 30 May 05 jari 342
435 14 Dec 05 markus 343   ///
4200 19 Aug 22 peter 344   /// @return true if string is "nan" (case-insensitive)
435 14 Dec 05 markus 345   ///
435 14 Dec 05 markus 346   bool is_nan(const std::string& s);
327 30 May 05 jari 347
1922 24 Apr 09 peter 348   /**
1922 24 Apr 09 peter 349      The std::istream will be interpreted as outlined here:
1789 10 Feb 09 peter 350
1922 24 Apr 09 peter 351      Lines are separated by character \a line_sep and rows are
4200 19 Aug 22 peter 352      separated by character \a sep.
4200 19 Aug 22 peter 353
1922 24 Apr 09 peter 354      The first line is read into a stringstream, which is used to
1922 24 Apr 09 peter 355      load the first vector (vec[0]) with elements using
1922 24 Apr 09 peter 356      load(stringstream, vec[0], sep).
4200 19 Aug 22 peter 357
1922 24 Apr 09 peter 358      Therefore, column elements separation has two modes depending
1922 24 Apr 09 peter 359      on the value of \a sep.
4200 19 Aug 22 peter 360
1922 24 Apr 09 peter 361      - If \a sep is the default '\\0' value then column elements are
1922 24 Apr 09 peter 362      separated with white space characters except the new line
1922 24 Apr 09 peter 363      character. Multiple sequential white space characters are treated
1922 24 Apr 09 peter 364      as one separator.
4200 19 Aug 22 peter 365
1922 24 Apr 09 peter 366      - Setting \a sep to something else than the default value will
1922 24 Apr 09 peter 367      change the behaviour to use the \a sep character as the separator
1922 24 Apr 09 peter 368      between column elements. Multiple sequential \a sep characters
1922 24 Apr 09 peter 369      will be treated as separating elements with missing values.
1922 24 Apr 09 peter 370
1928 30 Apr 09 peter 371      If \a rectangle is true, rows must contain same number of
1928 30 Apr 09 peter 372      elements or function will throw.
1922 24 Apr 09 peter 373
1928 30 Apr 09 peter 374      If \a ignore_empty is true empty lines are ignored.
1928 30 Apr 09 peter 375
1922 24 Apr 09 peter 376      \see load(std::istream&, std::vector<T>&, char sep='\\0')
1922 24 Apr 09 peter 377
1922 24 Apr 09 peter 378      \note Requirement on T: utility::convert<T> must be supported
2248 22 Apr 10 peter 379      (from yat 0.7 T=string is also supported)
1971 11 May 09 peter 380
1971 11 May 09 peter 381      \since New in yat 0.6
1922 24 Apr 09 peter 382    */
1922 24 Apr 09 peter 383   template<typename T>
4200 19 Aug 22 peter 384   void load(std::istream& is, std::vector<std::vector<T> >& vec, char sep='\0',
1928 30 Apr 09 peter 385             char line_sep='\n', bool ignore_empty=false, bool rectangle=true);
1922 24 Apr 09 peter 386
1922 24 Apr 09 peter 387   /**
1922 24 Apr 09 peter 388      \brief Fill a vector<T> with elements from istream
1922 24 Apr 09 peter 389
1922 24 Apr 09 peter 390      Element separation has two modes depending on the value of \a
1922 24 Apr 09 peter 391      sep.
4200 19 Aug 22 peter 392
1922 24 Apr 09 peter 393      - If \a sep is the default '\\0' value then elements are
1922 24 Apr 09 peter 394      separated with white space characters. Multiple sequential white
1922 24 Apr 09 peter 395      space characters are treated as one separator.
4200 19 Aug 22 peter 396
1922 24 Apr 09 peter 397      - Setting \a sep to something else than the default value will
1922 24 Apr 09 peter 398      change the behaviour to use the \a sep character as the
1922 24 Apr 09 peter 399      separator between column elements. Multiple sequential \a sep
1922 24 Apr 09 peter 400      characters will be treated as separating elements with missing
1922 24 Apr 09 peter 401      values. Missing values are set to std::numeric_limits<T>::quiet_NaN
4200 19 Aug 22 peter 402
1922 24 Apr 09 peter 403      \note Requirement on T: utility::convert<T> must be supported
2248 22 Apr 10 peter 404      (from yat 0.7 T=string is also supported)
1971 11 May 09 peter 405
1971 11 May 09 peter 406      \since New in yat 0.6
1922 24 Apr 09 peter 407    */
1922 24 Apr 09 peter 408   template<typename T>
1922 24 Apr 09 peter 409   void load(std::istream& is, std::vector<T>& vec, char sep='\0');
2867 12 Nov 12 peter 410
2867 12 Nov 12 peter 411   /**
2867 12 Nov 12 peter 412      \return base-2 logarithm of x
2867 12 Nov 12 peter 413
3507 19 Jul 16 peter 414      Implemented for \c float, \c double, and \c long \c double.
3507 19 Jul 16 peter 415
2867 12 Nov 12 peter 416      \since New in yat 0.10
2867 12 Nov 12 peter 417    */
2867 12 Nov 12 peter 418   template<typename T>
3640 03 May 17 peter 419   T log2(T x) { return std::log2(x); }
2867 12 Nov 12 peter 420
3287 12 Jul 14 peter 421   /**
3287 12 Jul 14 peter 422      \brief create a directory \a dir
3287 12 Jul 14 peter 423
3287 12 Jul 14 peter 424      \see http://linux.die.net/man/3/mkdir
3287 12 Jul 14 peter 425
3287 12 Jul 14 peter 426      \throw runtime_error if creation failed
3287 12 Jul 14 peter 427
3287 12 Jul 14 peter 428      \since New in yat 0.10
3287 12 Jul 14 peter 429    */
3287 12 Jul 14 peter 430   void mkdir(const std::string& dir, mode_t mode=0777);
3287 12 Jul 14 peter 431
3287 12 Jul 14 peter 432   /**
3287 12 Jul 14 peter 433      Similar to mkdir(const std::string&, mode_t).
3287 12 Jul 14 peter 434
3287 12 Jul 14 peter 435      No error if \a dir already exist. Make parent directories as needed.
3287 12 Jul 14 peter 436
3287 12 Jul 14 peter 437      \since New in yat 0.10
3287 12 Jul 14 peter 438    */
3287 12 Jul 14 peter 439   void mkdir_p(const std::string& dir, mode_t mode=0777);
3287 12 Jul 14 peter 440
3287 12 Jul 14 peter 441   /**
3722 21 Nov 17 peter 442      Preprocessor macro that works like std::move, but also works when
3722 21 Nov 17 peter 443      rvalue is not available (in which case arg is returned).
3722 21 Nov 17 peter 444
3722 21 Nov 17 peter 445      \since new in yat 0.16
3722 21 Nov 17 peter 446    */
3722 21 Nov 17 peter 447 #define YAT_MOVE(arg) std::move(arg)
3722 21 Nov 17 peter 448   /// likewise for std::move_if_noexcept
3722 21 Nov 17 peter 449 #define YAT_MOVE_IF_NOEXCEPT(arg) std::move_if_noexcept(arg)
3722 21 Nov 17 peter 450
3722 21 Nov 17 peter 451   /**
3730 10 Apr 18 peter 452      \brief recursively print exception what
3730 10 Apr 18 peter 453
3938 16 Jul 20 peter 454      Print \c what() of \a error to \a out. If \a error is nested, the
3938 16 Jul 20 peter 455      exception that is nested in \a error is passed to print_what().
3730 10 Apr 18 peter 456
3730 10 Apr 18 peter 457      \note If nested exception is null, function calls terminate (this
3730 10 Apr 18 peter 458      behaviour might change in the future).
3730 10 Apr 18 peter 459
3730 10 Apr 18 peter 460      \since new in yat 0.16
3730 10 Apr 18 peter 461    */
3730 10 Apr 18 peter 462   void print_what(const std::exception& error, std::ostream& out=std::cerr);
3730 10 Apr 18 peter 463
3730 10 Apr 18 peter 464   /**
3287 12 Jul 14 peter 465      same as C function remove but throws errno_error at failure
3287 12 Jul 14 peter 466
3287 12 Jul 14 peter 467      \see http://linux.die.net/man/3/remove
3287 12 Jul 14 peter 468
3295 25 Jul 14 peter 469      \since New in yat 0.12
3287 12 Jul 14 peter 470    */
3287 12 Jul 14 peter 471   void remove(const std::string& fn);
3287 12 Jul 14 peter 472
3287 12 Jul 14 peter 473   /**
3287 12 Jul 14 peter 474      same as C function with same name but throws errno_error if error
3287 12 Jul 14 peter 475      is encountered
3287 12 Jul 14 peter 476
3287 12 Jul 14 peter 477      \see http://linux.die.net/man/3/rename
3287 12 Jul 14 peter 478
3295 25 Jul 14 peter 479      \since New in yat 0.12
3287 12 Jul 14 peter 480    */
3397 24 Mar 15 peter 481   void rename(const std::string& from, const std::string& to);
3287 12 Jul 14 peter 482
3287 12 Jul 14 peter 483   /**
3287 12 Jul 14 peter 484      In \a full_str replace every sub-string \a old_str with \a
3287 12 Jul 14 peter 485      new_str;
3287 12 Jul 14 peter 486
3287 12 Jul 14 peter 487      \since New in yat 0.10
4097 17 Sep 21 peter 488
4097 17 Sep 21 peter 489      \see <a href=https://www.boost.org/doc/libs/1_77_0/doc/html/boost/algorithm/replace_all.html>
4098 17 Sep 21 peter 490      boost::algorithm::replace_all</a>(string&, const string&, const string&)
3287 12 Jul 14 peter 491    */
4097 17 Sep 21 peter 492   void replace(std::string& full_str, const std::string& old_str,
4097 17 Sep 21 peter 493                const std::string& new_str);
3287 12 Jul 14 peter 494
3287 12 Jul 14 peter 495
3287 12 Jul 14 peter 496   /**
4102 22 Sep 21 peter 497      \return true if string \a str starts with \a prefix
4102 22 Sep 21 peter 498
4102 22 Sep 21 peter 499      \see https://en.cppreference.com/w/cpp/string/basic_string/starts_with
4102 22 Sep 21 peter 500
4102 22 Sep 21 peter 501      \since New in yat 0.20
4102 22 Sep 21 peter 502    */
4102 22 Sep 21 peter 503   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 504   bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 505                    const std::basic_string<charT, Traits, Allocator>& prefix);
4102 22 Sep 21 peter 506
4102 22 Sep 21 peter 507   /// since New in yat 0.20
4102 22 Sep 21 peter 508   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 509   bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 510                    charT prefix);
4102 22 Sep 21 peter 511
4102 22 Sep 21 peter 512   /// since New in yat 0.20
4102 22 Sep 21 peter 513   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 514   bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 515                    const charT* prefix);
4102 22 Sep 21 peter 516
4102 22 Sep 21 peter 517   /**
3287 12 Jul 14 peter 518      Calculate sum of weights in range [first, last). The complexity
3287 12 Jul 14 peter 519      is linear except in the important case when \c Iterator is
3287 12 Jul 14 peter 520      unweighted and \random_access_iterator when complexity is constant.
3287 12 Jul 14 peter 521
3287 12 Jul 14 peter 522      Type Requirments:
3287 12 Jul 14 peter 523      - \c Iterator is \ref concept_data_iterator
3287 12 Jul 14 peter 524      - \c Iterator is \readable_iterator
3287 12 Jul 14 peter 525      - \c Iterator is \single_pass_iterator
3288 12 Jul 14 peter 526
3288 12 Jul 14 peter 527      \since New in yat 0.13
3287 12 Jul 14 peter 528    */
3287 12 Jul 14 peter 529   template<typename Iterator>
3287 12 Jul 14 peter 530   double sum_weight(Iterator first, Iterator last);
3287 12 Jul 14 peter 531
3746 13 Aug 18 peter 532   /**
3746 13 Aug 18 peter 533      same as C function symlink but throws errno_error at failure
3746 13 Aug 18 peter 534
3746 13 Aug 18 peter 535      Creates a symbolic link called \a path2 that contains the string
3746 13 Aug 18 peter 536      pointed to by \a path1
3746 13 Aug 18 peter 537
3746 13 Aug 18 peter 538      \see http://linux.die.net/man/3/symlink
3746 13 Aug 18 peter 539
3746 13 Aug 18 peter 540      \since New in yat 0.16
3746 13 Aug 18 peter 541    */
3746 13 Aug 18 peter 542   void symlink(const std::string& path1, const std::string& path2);
3746 13 Aug 18 peter 543
3188 25 Mar 14 peter 544 /// \cond IGNORE_DOXYGEN
3188 25 Mar 14 peter 545
2248 22 Apr 10 peter 546 // private namespace
2248 22 Apr 10 peter 547 namespace detail {
2270 14 Jun 10 peter 548
2248 22 Apr 10 peter 549   /**
2248 22 Apr 10 peter 550      Functor used in load function
2248 22 Apr 10 peter 551    */
2248 22 Apr 10 peter 552   template<typename T>
2248 22 Apr 10 peter 553   struct VectorPusher
2248 22 Apr 10 peter 554   {
2248 22 Apr 10 peter 555     /**
2248 22 Apr 10 peter 556        convert element to T and push on vec's back
2248 22 Apr 10 peter 557
2248 22 Apr 10 peter 558        \internal
2248 22 Apr 10 peter 559      */
2248 22 Apr 10 peter 560     void operator()(const std::string& element, std::vector<T>& vec)
3287 12 Jul 14 peter 561     {
2248 22 Apr 10 peter 562       if (!element.size())
2248 22 Apr 10 peter 563         vec.push_back(std::numeric_limits<T>::quiet_NaN());
2248 22 Apr 10 peter 564       else {
4125 14 Jan 22 peter 565         vec.push_back(convert<T>(element));
2248 22 Apr 10 peter 566       }
2248 22 Apr 10 peter 567     }
2248 22 Apr 10 peter 568   };
2248 22 Apr 10 peter 569
2248 22 Apr 10 peter 570   /**
2248 22 Apr 10 peter 571      specialization for string
2248 22 Apr 10 peter 572
2248 22 Apr 10 peter 573      \internal
2248 22 Apr 10 peter 574    */
2248 22 Apr 10 peter 575   template<>
2248 22 Apr 10 peter 576   struct VectorPusher<std::string>
2248 22 Apr 10 peter 577   {
2248 22 Apr 10 peter 578     /**
2248 22 Apr 10 peter 579        push element on vec's back
2248 22 Apr 10 peter 580      */
2248 22 Apr 10 peter 581     void operator()(const std::string& element, std::vector<std::string>& vec)
3777 31 Oct 18 peter 582     {
2248 22 Apr 10 peter 583       vec.push_back(element);
2248 22 Apr 10 peter 584     }
3777 31 Oct 18 peter 585
3777 31 Oct 18 peter 586     void operator()(std::string&& element, std::vector<std::string>& vec)
3777 31 Oct 18 peter 587     {
3777 31 Oct 18 peter 588       vec.push_back(std::move(element));
3777 31 Oct 18 peter 589     }
2248 22 Apr 10 peter 590   };
2248 22 Apr 10 peter 591
2248 22 Apr 10 peter 592
3287 12 Jul 14 peter 593   template<typename Iterator>
3287 12 Jul 14 peter 594   double sum_weight(Iterator first, Iterator last, unweighted_iterator_tag tag)
3287 12 Jul 14 peter 595   {
3287 12 Jul 14 peter 596     return std::distance(first, last);
3287 12 Jul 14 peter 597   }
2248 22 Apr 10 peter 598
3188 25 Mar 14 peter 599
3287 12 Jul 14 peter 600   template<typename Iterator>
3287 12 Jul 14 peter 601   double sum_weight(Iterator first, Iterator last, weighted_iterator_tag tag)
3287 12 Jul 14 peter 602   {
3287 12 Jul 14 peter 603     return std::accumulate(weight_iterator(first), weight_iterator(last), 0);
3287 12 Jul 14 peter 604   }
2892 09 Dec 12 peter 605
2907 15 Dec 12 peter 606
3287 12 Jul 14 peter 607 } // end of namespace detail
3066 14 Jul 13 peter 608
3287 12 Jul 14 peter 609 /// \endcond
2892 09 Dec 12 peter 610
1922 24 Apr 09 peter 611   // template implementations
1922 24 Apr 09 peter 612
1789 10 Feb 09 peter 613   template<typename InputIterator, typename OutputIterator>
4200 19 Aug 22 peter 614   bool binary_weight(InputIterator first, InputIterator last,
1807 18 Feb 09 peter 615                      OutputIterator result)
1789 10 Feb 09 peter 616   {
3507 19 Jul 16 peter 617     BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<InputIterator>));
3507 19 Jul 16 peter 618     BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<InputIterator>));
3507 19 Jul 16 peter 619     BOOST_CONCEPT_ASSERT((boost_concepts::IncrementableIterator<OutputIterator>));
3507 19 Jul 16 peter 620     BOOST_CONCEPT_ASSERT((boost_concepts::WritableIterator<OutputIterator, float>));
3507 19 Jul 16 peter 621
1789 10 Feb 09 peter 622     bool nan=false;
1789 10 Feb 09 peter 623     while (first!=last) {
1789 10 Feb 09 peter 624       if (std::isnan(*first)) {
1789 10 Feb 09 peter 625         *result=0;
1789 10 Feb 09 peter 626         nan=true;
1789 10 Feb 09 peter 627       }
1789 10 Feb 09 peter 628       else
1789 10 Feb 09 peter 629         *result = 1.0;
1789 10 Feb 09 peter 630       ++first;
1789 10 Feb 09 peter 631       ++result;
1789 10 Feb 09 peter 632     }
1789 10 Feb 09 peter 633     return nan;
1789 10 Feb 09 peter 634   }
1789 10 Feb 09 peter 635
1789 10 Feb 09 peter 636
4102 22 Sep 21 peter 637   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 638   bool contains(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 639                 const std::basic_string<charT, Traits, Allocator>& substr)
4102 22 Sep 21 peter 640   {
4262 10 Jan 23 peter 641 #ifdef YAT_HAVE_FUNC_STRING_CONTAINS
4262 10 Jan 23 peter 642     return str.contains(substr);
4262 10 Jan 23 peter 643 #else
4102 22 Sep 21 peter 644     return str.find(substr)!=std::basic_string<charT, Traits,Allocator>::npos;
4262 10 Jan 23 peter 645 #endif
4102 22 Sep 21 peter 646   }
4102 22 Sep 21 peter 647
4102 22 Sep 21 peter 648
4102 22 Sep 21 peter 649   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 650   bool contains(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 651                 charT substr)
4102 22 Sep 21 peter 652   {
4262 10 Jan 23 peter 653 #ifdef YAT_HAVE_FUNC_STRING_CONTAINS
4262 10 Jan 23 peter 654     return str.contains(substr);
4262 10 Jan 23 peter 655 #else
4102 22 Sep 21 peter 656     return str.find(substr)!=std::basic_string<charT, Traits,Allocator>::npos;
4262 10 Jan 23 peter 657 #endif
4102 22 Sep 21 peter 658   }
4102 22 Sep 21 peter 659
4102 22 Sep 21 peter 660
4102 22 Sep 21 peter 661   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 662   bool contains(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 663                 const charT* substr)
4102 22 Sep 21 peter 664   {
4262 10 Jan 23 peter 665 #ifdef YAT_HAVE_FUNC_STRING_CONTAINS
4262 10 Jan 23 peter 666     return str.contains(substr);
4262 10 Jan 23 peter 667 #else
4102 22 Sep 21 peter 668     return str.find(substr)!=std::basic_string<charT, Traits,Allocator>::npos;
4262 10 Jan 23 peter 669 #endif
4102 22 Sep 21 peter 670   }
4102 22 Sep 21 peter 671
4102 22 Sep 21 peter 672
1057 07 Feb 08 peter 673   template<typename T>
2426 13 Feb 11 peter 674   std::string convert(T input)
2426 13 Feb 11 peter 675   {
2426 13 Feb 11 peter 676     std::ostringstream ss;
2426 13 Feb 11 peter 677     ss << input;
2426 13 Feb 11 peter 678     return ss.str();
2426 13 Feb 11 peter 679   }
2426 13 Feb 11 peter 680
2426 13 Feb 11 peter 681
2426 13 Feb 11 peter 682   template<typename T>
1057 07 Feb 08 peter 683   T convert(const std::string& s)
1057 07 Feb 08 peter 684   {
2270 14 Jun 10 peter 685     T result;
3597 22 Jan 17 peter 686     if (!convert_try(s, result))
2210 05 Mar 10 peter 687       throw runtime_error(std::string("yat::utility::convert(\"")+s+
2210 05 Mar 10 peter 688                           std::string("\")"));
2270 14 Jun 10 peter 689     return result;
1057 07 Feb 08 peter 690   }
1057 07 Feb 08 peter 691
2270 14 Jun 10 peter 692
4102 22 Sep 21 peter 693   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 694   bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 695                  const std::basic_string<charT, Traits, Allocator>& suffix)
4102 22 Sep 21 peter 696   {
4102 22 Sep 21 peter 697 #ifdef YAT_HAVE_FUNC_STRING_ENDS_WITH
4102 22 Sep 21 peter 698     return str.ends_with(suffix);
4102 22 Sep 21 peter 699 #else
4102 22 Sep 21 peter 700     size_t n = suffix.size();
4102 22 Sep 21 peter 701     return n <= str.size() && !str.compare(str.size()-n, n, suffix);
4102 22 Sep 21 peter 702 #endif
4102 22 Sep 21 peter 703   }
4102 22 Sep 21 peter 704
4102 22 Sep 21 peter 705
4102 22 Sep 21 peter 706   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 707   bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 708                  charT suffix)
4102 22 Sep 21 peter 709   {
4102 22 Sep 21 peter 710 #ifdef YAT_HAVE_FUNC_STRING_ENDS_WITH
4102 22 Sep 21 peter 711     return str.ends_with(suffix);
4102 22 Sep 21 peter 712 #else
4102 22 Sep 21 peter 713     Traits traits;
4102 22 Sep 21 peter 714     return str.size() && traits.eq(str.back(), suffix);
4102 22 Sep 21 peter 715 #endif
4102 22 Sep 21 peter 716   }
4102 22 Sep 21 peter 717
4102 22 Sep 21 peter 718
4102 22 Sep 21 peter 719   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 720   bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 721                  const charT* suffix)
4102 22 Sep 21 peter 722   {
4102 22 Sep 21 peter 723 #ifdef YAT_HAVE_FUNC_STRING_ENDS_WITH
4102 22 Sep 21 peter 724     return str.ends_with(suffix);
4102 22 Sep 21 peter 725 #else
4102 22 Sep 21 peter 726     Traits traits;
4102 22 Sep 21 peter 727     size_t n = traits.length(suffix);
4102 22 Sep 21 peter 728     return n <= str.size() && !str.compare(str.size()-n, n, suffix);
4102 22 Sep 21 peter 729 #endif
4102 22 Sep 21 peter 730   }
4102 22 Sep 21 peter 731
4102 22 Sep 21 peter 732
1312 19 May 08 peter 733   template<typename T>
1312 19 May 08 peter 734   bool is(const std::string& s)
1312 19 May 08 peter 735   {
2270 14 Jun 10 peter 736     T tmp;
3597 22 Jan 17 peter 737     return convert_try(s, tmp);
1312 19 May 08 peter 738   }
1312 19 May 08 peter 739
2270 14 Jun 10 peter 740
1922 24 Apr 09 peter 741   template<typename T>
3287 12 Jul 14 peter 742   void load(std::istream& is, std::vector<std::vector<T> >& matrix,
3287 12 Jul 14 peter 743             char sep, char line_sep, bool ignore_empty,
1928 30 Apr 09 peter 744             bool rectangle)
1922 24 Apr 09 peter 745   {
1922 24 Apr 09 peter 746     size_t nof_columns=0;
1922 24 Apr 09 peter 747     std::string line;
1922 24 Apr 09 peter 748     while(getline(is, line, line_sep)){
1928 30 Apr 09 peter 749       if (line.empty() && ignore_empty)
1928 30 Apr 09 peter 750         continue;
3993 21 Sep 20 peter 751       std::vector<T> v;
1922 24 Apr 09 peter 752       v.reserve(nof_columns);
3956 24 Jul 20 peter 753       bool empty_last_element = !line.empty() && line.back()==sep;
3955 23 Jul 20 peter 754       std::stringstream ss(std::move(line));
1922 24 Apr 09 peter 755       load(ss, v, sep);
2273 15 Jun 10 peter 756       // add NaN for final separator (or empty string if T=std::string)
2273 15 Jun 10 peter 757       detail::VectorPusher<T> pusher;
3924 21 Jun 20 peter 758       if (empty_last_element && sep!='\0')
2273 15 Jun 10 peter 759         pusher("", v);
3287 12 Jul 14 peter 760
1928 30 Apr 09 peter 761       if (rectangle && nof_columns && v.size()!=nof_columns) {
1928 30 Apr 09 peter 762         std::ostringstream s;
2386 22 Dec 10 peter 763         s << "load stream error: "
1928 30 Apr 09 peter 764           << "line " << matrix.size() << " has " << v.size()
1928 30 Apr 09 peter 765           << " columns; expected " << nof_columns  << " columns.";
1928 30 Apr 09 peter 766         throw utility::IO_error(s.str());
3287 12 Jul 14 peter 767       }
1922 24 Apr 09 peter 768       nof_columns = std::max(nof_columns, v.size());
3993 21 Sep 20 peter 769       matrix.push_back(std::move(v));
1922 24 Apr 09 peter 770     }
1922 24 Apr 09 peter 771
1922 24 Apr 09 peter 772     // manipulate the state of the stream to be good
1922 24 Apr 09 peter 773     is.clear(std::ios::goodbit);
1922 24 Apr 09 peter 774   }
1922 24 Apr 09 peter 775
1922 24 Apr 09 peter 776   template<typename T>
2673 03 Dec 11 peter 777   void load(std::istream& is, std::vector<T>& vec, char sep)
1922 24 Apr 09 peter 778   {
2248 22 Apr 10 peter 779     detail::VectorPusher<T> pusher;
2248 22 Apr 10 peter 780     while(true) {
3778 31 Oct 18 peter 781       std::string element;
1922 24 Apr 09 peter 782       if(sep=='\0')
3994 22 Sep 20 peter 783         is>>element;
1922 24 Apr 09 peter 784       else
3994 22 Sep 20 peter 785         getline(is, element, sep);
3994 22 Sep 20 peter 786       if(is.fail())
1922 24 Apr 09 peter 787         break;
3955 23 Jul 20 peter 788       pusher(std::move(element), vec);
1922 24 Apr 09 peter 789     }
2906 15 Dec 12 peter 790   }
1922 24 Apr 09 peter 791
3287 12 Jul 14 peter 792
4102 22 Sep 21 peter 793   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 794   bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 795                    const std::basic_string<charT, Traits, Allocator>& prefix)
4102 22 Sep 21 peter 796   {
4102 22 Sep 21 peter 797 #ifdef YAT_HAVE_FUNC_STRING_STARTS_WITH
4102 22 Sep 21 peter 798     return str.starts_with(prefix);
4102 22 Sep 21 peter 799 #else
4102 22 Sep 21 peter 800     size_t n = prefix.size();
4102 22 Sep 21 peter 801     return n <= str.size() && !str.compare(0, n, prefix);
4102 22 Sep 21 peter 802 #endif
4102 22 Sep 21 peter 803   }
4102 22 Sep 21 peter 804
4102 22 Sep 21 peter 805
4102 22 Sep 21 peter 806   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 807   bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 808                    charT prefix)
4102 22 Sep 21 peter 809   {
4102 22 Sep 21 peter 810 #ifdef YAT_HAVE_FUNC_STRING_STARTS_WITH
4102 22 Sep 21 peter 811     return str.starts_with(prefix);
4102 22 Sep 21 peter 812 #else
4102 22 Sep 21 peter 813     Traits traits;
4102 22 Sep 21 peter 814     return str.size() && traits.eq(str[0], prefix);
4102 22 Sep 21 peter 815 #endif
4102 22 Sep 21 peter 816   }
4102 22 Sep 21 peter 817
4102 22 Sep 21 peter 818
4102 22 Sep 21 peter 819   template<typename charT, class Traits, class Allocator>
4102 22 Sep 21 peter 820   bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
4102 22 Sep 21 peter 821                    const charT* prefix)
4102 22 Sep 21 peter 822   {
4102 22 Sep 21 peter 823 #ifdef YAT_HAVE_FUNC_STRING_STARTS_WITH
4102 22 Sep 21 peter 824     return str.starts_with(prefix);
4102 22 Sep 21 peter 825 #else
4102 22 Sep 21 peter 826     Traits traits;
4102 22 Sep 21 peter 827     size_t n = traits.length(prefix);
4102 22 Sep 21 peter 828     return n <= str.size() && !str.compare(0, n, prefix);
4102 22 Sep 21 peter 829 #endif
4102 22 Sep 21 peter 830   }
4102 22 Sep 21 peter 831
4102 22 Sep 21 peter 832
3287 12 Jul 14 peter 833   template<typename Iterator>
3287 12 Jul 14 peter 834   double sum_weight(Iterator first, Iterator last)
3287 12 Jul 14 peter 835   {
3287 12 Jul 14 peter 836     BOOST_CONCEPT_ASSERT((DataIteratorConcept<Iterator>));
3287 12 Jul 14 peter 837     BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<Iterator>));
3287 12 Jul 14 peter 838     BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<Iterator>));
3287 12 Jul 14 peter 839     typename weighted_iterator_traits<Iterator>::type tag;
3287 12 Jul 14 peter 840     return detail::sum_weight(first, last, tag);
3287 12 Jul 14 peter 841   }
3287 12 Jul 14 peter 842
3287 12 Jul 14 peter 843
3597 22 Jan 17 peter 844
2270 14 Jun 10 peter 845   template<typename T>
3597 22 Jan 17 peter 846   bool convert_try(const std::string& s, T& result)
2270 14 Jun 10 peter 847   {
2673 03 Dec 11 peter 848     if (!std::numeric_limits<T>::is_signed) {
2673 03 Dec 11 peter 849       // first non-whitespace character
2673 03 Dec 11 peter 850       std::string::const_iterator iter = s.begin();
2673 03 Dec 11 peter 851       while (iter!=s.end() && std::isspace(*iter))
2673 03 Dec 11 peter 852         ++iter;
2673 03 Dec 11 peter 853       // unsigned int cannot start with a '-' and with some compilers
2673 03 Dec 11 peter 854       // operation ss >> result won't fail so catch it like this instead.
2673 03 Dec 11 peter 855       if (iter==s.end() || *iter=='-')
2673 03 Dec 11 peter 856         return false;
2673 03 Dec 11 peter 857     }
2270 14 Jun 10 peter 858     std::istringstream ss(s);
2270 14 Jun 10 peter 859     ss >> result;
2270 14 Jun 10 peter 860     if (ss.fail()) {
3177 15 Mar 14 peter 861       if (is_nan(s) || is_equal(s, "-nan")) {
2270 14 Jun 10 peter 862         result = std::numeric_limits<T>::quiet_NaN();
2270 14 Jun 10 peter 863         return true;
2270 14 Jun 10 peter 864       }
2270 14 Jun 10 peter 865       if (is_equal(s, "inf")) {
2270 14 Jun 10 peter 866         result = std::numeric_limits<T>::infinity();
2270 14 Jun 10 peter 867         return true;
2270 14 Jun 10 peter 868       }
2818 29 Aug 12 peter 869       if (is_equal(s, "-inf")) {
2818 29 Aug 12 peter 870         // unsigned types are caught in prologue
2818 29 Aug 12 peter 871         YAT_ASSERT(std::numeric_limits<T>::is_signed);
2270 14 Jun 10 peter 872         result = -std::numeric_limits<T>::infinity();
2270 14 Jun 10 peter 873         return true;
2270 14 Jun 10 peter 874       }
2270 14 Jun 10 peter 875       return false;
2270 14 Jun 10 peter 876     }
2270 14 Jun 10 peter 877     // Check that nothing is left on stream
2270 14 Jun 10 peter 878     std::string b;
2270 14 Jun 10 peter 879     ss >> b;
2270 14 Jun 10 peter 880     return b.empty();
2270 14 Jun 10 peter 881   }
2270 14 Jun 10 peter 882
687 16 Oct 06 jari 883 }}} // of namespace utility, yat, and theplu
616 31 Aug 06 jari 884
327 30 May 05 jari 885 #endif