Skip to content
Snippets Groups Projects
Strings.cpp 37.7 KiB
Newer Older
      it1 = it2;
      continue;
    }
    path_components[ic] = folder;
    ic++;
    it1 = it2;
  }

  n_folders = size_t(ic);
  path_components.resize(n_folders);
  return n_folders;
}

/**
 * Function checks if the candidate is the member of the group
 * @param group :: vector of string to check
 * @param candidate :: the string which has to be checked against the group
 * @returns :: number of the candidate in the input vector of strings if the
 candidate belongs to the group
               or -1 if it does not.
               Returns the number of the first maching entry in the group if
 there are duplicated entries in the group
 */
int isMember(const std::vector<std::string> &group,
             const std::string &candidate) {
  int num(-1);
  for (size_t i = 0; i < group.size(); i++) {
    if (candidate.compare(group[i]) == 0) {
      num = int(i);
      return num;
    }
  }
  return num;
}

/**
 * Parses a number range, e.g. "1,4-9,54-111,3,10", to the vector containing all
 * the elements
 * within the range.
 * @param str String to parse
 * @param elemSep String with characters used to separate elements (',')
 * @param rangeSep String with characters used to separate range start and end
 * ('-')
 * @return A vector with all the elements from the range
 */
std::vector<int> parseRange(const std::string &str, const std::string &elemSep,
                            const std::string &rangeSep) {
  typedef Poco::StringTokenizer Tokenizer;

  boost::shared_ptr<Tokenizer> elements;

  if (elemSep.find(' ') != std::string::npos) {
    // If element separator contains space character it's a special case,
    // because in that case
    // it is allowed to have element separator inside a range, e.g. "4 - 5", but
    // not "4,-5"

    // Space is added so that last empty element of the "1,2,3-" is not ignored
    // and we can
    // spot the error. Behaviour is changed in Poco 1.5 and this will not be
    // needed.
    Tokenizer ranges(str + " ", rangeSep, Tokenizer::TOK_TRIM);
    std::string new_str =
        join(ranges.begin(), ranges.end(), rangeSep.substr(0, 1));

    elements = boost::make_shared<Tokenizer>(
        new_str, elemSep, Tokenizer::TOK_IGNORE_EMPTY | Tokenizer::TOK_TRIM);
  } else {
    elements = boost::make_shared<Tokenizer>(
        str, elemSep, Tokenizer::TOK_IGNORE_EMPTY | Tokenizer::TOK_TRIM);
  }

  std::vector<int> result;

  // Estimation of the resulting number of elements
  result.reserve(elements->count());

  for (Tokenizer::Iterator it = elements->begin(); it != elements->end();
       it++) {
    // See above for the reason space is added
    Tokenizer rangeElements(*it + " ", rangeSep, Tokenizer::TOK_TRIM);

    size_t noOfRangeElements = rangeElements.count();

    // A single element
    if (noOfRangeElements == 1) {
      int element;
      if (convert(rangeElements[0], element) != 1)
        throw std::invalid_argument("Invalid element: " + *it);
      result.push_back(element);
    }
    // A pair
    else if (noOfRangeElements == 2) {
      int start, end;

      if (convert(rangeElements[0], start) != 1 ||
          convert(rangeElements[1], end) != 1)
        throw std::invalid_argument("Invalid range: " + *it);

      if (start >= end)
        throw std::invalid_argument("Range boundaries are reversed: " + *it);

      for (int i = start; i <= end; i++)
        result.push_back(i);
    }
    // Error - e.g. "--""
    else {
      throw std::invalid_argument("Multiple range separators: " + *it);
    }
  }

  return result;
}

/**
* Extract a string until an EOL character is reached. There are 3 scenarios that
* we need to deal with
* 1) Windows-style  - CRLF ('\\r\\n');
* 2) Unix-style     - LF ('\\n');
* 3) Old MAC style  - CR ('\\r').
* This function will give the string preceding any of these sequences
* @param is :: The input stream to read from
* @param str :: The output string to use to accumulate the line
* @returns A reference to the input stream
*/
std::istream &extractToEOL(std::istream &is, std::string &str) {
  // Empty the string
  str = "";
  char c('\0');
  while (is.get(c)) {
    if (c == '\r') {
      c = static_cast<char>(is.peek());
      if (c == '\n') {
        // Extract this as well
        is.get();
      break;
    } else if (c == '\n') {
      break;
    } else {
      // Accumulate the string
      str += c;
    }
  }
  return is;
}

/// \cond TEMPLATE
template MANTID_KERNEL_DLL int section(std::string &, double &);
template MANTID_KERNEL_DLL int section(std::string &, float &);
template MANTID_KERNEL_DLL int section(std::string &, int &);
template MANTID_KERNEL_DLL int section(std::string &, std::string &);

template MANTID_KERNEL_DLL int sectPartNum(std::string &, double &);
template MANTID_KERNEL_DLL int sectPartNum(std::string &, int &);
template MANTID_KERNEL_DLL int sectionMCNPX(std::string &, double &);

template MANTID_KERNEL_DLL int convert(const std::string &, double &);
template MANTID_KERNEL_DLL int convert(const std::string &, float &);
template MANTID_KERNEL_DLL int convert(const std::string &, std::string &);
template MANTID_KERNEL_DLL int convert(const std::string &, int &);
template MANTID_KERNEL_DLL int convert(const std::string &, std::size_t &);
template MANTID_KERNEL_DLL int convert(const std::string &, bool &);
template MANTID_KERNEL_DLL int convert(const char *, std::string &);
template MANTID_KERNEL_DLL int convert(const char *, double &);
template MANTID_KERNEL_DLL int convert(const char *, int &);
template MANTID_KERNEL_DLL int convert(const char *, std::size_t &);
template MANTID_KERNEL_DLL int convert(const char *, bool &);

template MANTID_KERNEL_DLL std::string toString(const double &value);
template MANTID_KERNEL_DLL std::string toString(const float &value);
template MANTID_KERNEL_DLL std::string toString(const int &value);
template MANTID_KERNEL_DLL std::string toString(const uint16_t &value);
template MANTID_KERNEL_DLL std::string
toString(const size_t &value); // Matches uint64_t on Linux 64 & Win 64
#if defined(__APPLE__) || (defined(_WIN32) && !defined(_WIN64)) ||             \
    (defined(__GNUC__) && !defined(__LP64__)) // Mac or 32-bit compiler
template MANTID_KERNEL_DLL std::string toString(const uint64_t &value);
template MANTID_KERNEL_DLL std::string toString(const std::string &value);

template MANTID_KERNEL_DLL std::string toString(const std::vector<int> &value);

// this block should generate the vector ones as well
template MANTID_KERNEL_DLL std::string toString(const std::set<int> &value);
template MANTID_KERNEL_DLL std::string toString(const std::set<int16_t> &value);
template MANTID_KERNEL_DLL std::string toString(
    const std::set<size_t> &value); // Matches uint64_t on Linux 64 & Win 64
#if defined(__APPLE__) || (defined(_WIN32) && !defined(_WIN64)) ||             \
    (defined(__GNUC__) && !defined(__LP64__)) // Mac or 32-bit compiler
template MANTID_KERNEL_DLL std::string
toString(const std::set<uint64_t> &value);
template MANTID_KERNEL_DLL int convPartNum(const std::string &, double &);
template MANTID_KERNEL_DLL int convPartNum(const std::string &, int &);

template MANTID_KERNEL_DLL int
setValues(const std::string &, const std::vector<int> &, std::vector<double> &);

template MANTID_KERNEL_DLL int writeFile(const std::string &, const double &,
                                         const std::vector<double> &);
template MANTID_KERNEL_DLL int writeFile(const std::string &,
                                         const std::vector<double> &,
                                         const std::vector<double> &,
                                         const std::vector<double> &);
template MANTID_KERNEL_DLL int writeFile(const std::string &,
                                         const std::vector<double> &,
                                         const std::vector<double> &);
template MANTID_KERNEL_DLL int writeFile(const std::string &,
                                         const std::vector<float> &,
                                         const std::vector<float> &);
template MANTID_KERNEL_DLL int writeFile(const std::string &,
                                         const std::vector<float> &,
                                         const std::vector<float> &,
                                         const std::vector<float> &);
/// \endcond TEMPLATE

} // NAMESPACE Strings

} // NAMESPACE Kernel

} // NAMESPACE Mantid