18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file string_manip.h
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * std::string helpers
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002 OProfile authors
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifndef STRING_MANIP_H
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define STRING_MANIP_H
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <string>
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <vector>
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <sstream>
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdexcept>
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param str string
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param ch the characterto search
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * erase char from the begin of str to the last
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * occurence of ch from and return the string
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstd::string erase_to_last_of(std::string const & str, char ch);
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// split string s by first occurence of char c, returning the second part.
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// s is set to the first part. Neither include the split character
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstd::string split(std::string & s, char c);
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// return true if "prefix" is a prefix of "s", behavior is undefined
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// if prefix is an empty string
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool is_prefix(std::string const & s, std::string const & prefix);
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param str the string to tokenize
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param sep the separator_char
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * separate fields in a string in a list of token; field are
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * separated by the sep character, sep char can be escaped
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * by '\\' to specify a sep char in a token, '\\' not followed
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * by a sep is taken as it e.g. "\,\a" --> ",\a"
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstd::vector<std::string> separate_token(std::string const & str, char sep);
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// remove trim chars from start of input string return the new string
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstd::string ltrim(std::string const & str, std::string const & totrim = "\t ");
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// remove trim chars from end of input string return the new string
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstd::string rtrim(std::string const & str, std::string const & totrim = "\t ");
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// ltrim(rtrim(str))
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstd::string trim(std::string const & str, std::string const & totrim = "\t ");
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * format_percent - smart format of double percentage value
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param value - the value
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param int_width - the maximum integer integer width default to 2
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param frac_width - the fractionnary width default to 4
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param showpos - show + sign for positive values
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * This formats a percentage into exactly the given width and returns
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * it. If the integer part is larger than the given int_width, the
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * returned string will be wider. The returned string is never
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * shorter than (fract_with + int_width + 1)
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstd::string const
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddformat_percent(double value, size_t int_width,
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd               size_t frac_width, bool showpos = false);
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// prefered width to format percentage
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic unsigned int const percent_int_width = 2;
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic unsigned int const percent_fract_width = 4;
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic unsigned int const percent_width = percent_int_width + percent_fract_width + 1;
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param src  input parameter
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * convert From src to a T through an istringstream.
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Throws invalid_argument if conversion fail.
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Note that this is not as foolproof as boost's lexical_cast
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtemplate <typename To, typename From>
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddTo op_lexical_cast(From const & src)
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	std::ostringstream in;
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!(in << src))
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		throw std::invalid_argument("op_lexical_cast<T>()");
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	std::istringstream out(in.str());
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	To value;
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!(out >> value)) {
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		throw std::invalid_argument("op_lexical_cast<T>(\"" +
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		    in.str() +"\")");
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return value;
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// specialization accepting hexadecimal and octal number in input. Note that
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// op_lexical_cast<unsigned int>("0x23"); will fail because it call the
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// non specialized template.
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtemplate <>
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddunsigned int op_lexical_cast<unsigned int>(std::string const & str);
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif /* !STRING_MANIP_H */
108