Line data Source code
1 : // Author(s): Wieger Wesselink 2 : // Copyright: see the accompanying file COPYING or copy at 3 : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING 4 : // 5 : // Distributed under the Boost Software License, Version 1.0. 6 : // (See accompanying file LICENSE_1_0.txt or copy at 7 : // http://www.boost.org/LICENSE_1_0.txt) 8 : // 9 : /// \file mcrl2/utilities/parse_numbers.h 10 : /// \brief add your file description here. 11 : 12 : #ifndef MCRL2_UTILITIES_PARSE_NUMBERS_H 13 : #define MCRL2_UTILITIES_PARSE_NUMBERS_H 14 : 15 : #include <cctype> 16 : #include <cstddef> 17 : #include <string> 18 : #include <vector> 19 : 20 : #include "mcrl2/utilities/exception.h" 21 : 22 : namespace mcrl2 { 23 : 24 : namespace utilities { 25 : 26 : namespace detail { 27 : 28 : // Reads the next integer from the range [first, last), and the spaces behind it 29 : // Returns the position in the range after the next integer 30 : // Precondition: (first != last) && !std::isspace(*first) 31 : template <typename Iterator> 32 5462 : Iterator parse_next_natural_number(Iterator first, Iterator last, std::size_t& result) 33 : { 34 5462 : assert((first != last) && !std::isspace(*first)); 35 : 36 5462 : Iterator i = first; 37 5462 : result = 0; 38 : 39 : for (;;) 40 : { 41 6216 : if (*i < '0' || *i > '9') 42 : { 43 4 : throw mcrl2::runtime_error("could not read an integer from " + std::string(first, last)); 44 : } 45 6212 : result *= 10; 46 6212 : result += *i - '0'; 47 6212 : ++i; 48 6212 : if (i == last) 49 : { 50 2244 : break; 51 : } 52 3968 : if (std::isspace(*i)) 53 : { 54 3214 : ++i; 55 3216 : while (i != last && std::isspace(*i)) 56 : { 57 2 : ++i; 58 : } 59 3214 : break; 60 : } 61 : } 62 5458 : return i; 63 : } 64 : 65 : } // namespace detail 66 : 67 : /// \brief Parses a natural number from a string 68 : inline 69 1835 : std::size_t parse_natural_number(const std::string& text) 70 : { 71 1835 : auto first = text.begin(); 72 1835 : auto last = text.end(); 73 : 74 : // skip leading spaces 75 1842 : while (first != last && std::isspace(*first)) 76 : { 77 7 : ++first; 78 : } 79 : 80 1835 : if (first == last) 81 : { 82 2 : throw mcrl2::runtime_error("could not read an integer from " + text); 83 : } 84 : 85 : std::size_t value; 86 1833 : first = detail::parse_next_natural_number(first, last, value); 87 : 88 1832 : if (first != last) 89 : { 90 2 : throw mcrl2::runtime_error("could not read an integer from " + text); 91 : } 92 : 93 1830 : return value; 94 : } 95 : 96 : /// \brief Parses a sequence of natural numbers (separated by spaces) from a string 97 : inline 98 422 : std::vector<std::size_t> parse_natural_number_sequence(const std::string& text) 99 : { 100 422 : std::vector<std::size_t> result; 101 : 102 422 : auto first = text.begin(); 103 422 : auto last = text.end(); 104 : 105 : // skip leading spaces 106 427 : while (first != last && std::isspace(*first)) 107 : { 108 5 : ++first; 109 : } 110 : 111 4048 : while (first != last) 112 : { 113 : std::size_t value; 114 3629 : first = detail::parse_next_natural_number(first, last, value); 115 3626 : result.push_back(value); 116 : } 117 : 118 838 : return result; 119 3 : } 120 : 121 : } // namespace utilities 122 : 123 : } // namespace mcrl2 124 : 125 : #endif // MCRL2_UTILITIES_PARSE_NUMBERS_H