110448Snilay@cs.wisc.edu/* Copyright (c) 2012 Massachusetts Institute of Technology
210448Snilay@cs.wisc.edu *
310448Snilay@cs.wisc.edu * Permission is hereby granted, free of charge, to any person obtaining a copy
410448Snilay@cs.wisc.edu * of this software and associated documentation files (the "Software"), to deal
510448Snilay@cs.wisc.edu * in the Software without restriction, including without limitation the rights
610448Snilay@cs.wisc.edu * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
710448Snilay@cs.wisc.edu * copies of the Software, and to permit persons to whom the Software is
810448Snilay@cs.wisc.edu * furnished to do so, subject to the following conditions:
910448Snilay@cs.wisc.edu *
1010448Snilay@cs.wisc.edu * The above copyright notice and this permission notice shall be included in
1110448Snilay@cs.wisc.edu * all copies or substantial portions of the Software.
1210448Snilay@cs.wisc.edu *
1310448Snilay@cs.wisc.edu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1410448Snilay@cs.wisc.edu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1510448Snilay@cs.wisc.edu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1610448Snilay@cs.wisc.edu * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1710448Snilay@cs.wisc.edu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1810448Snilay@cs.wisc.edu * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1910448Snilay@cs.wisc.edu * THE SOFTWARE.
2010448Snilay@cs.wisc.edu */
2110448Snilay@cs.wisc.edu
2210447Snilay@cs.wisc.edu#ifndef __STRING_H__
2310447Snilay@cs.wisc.edu#define __STRING_H__
2410447Snilay@cs.wisc.edu
2510447Snilay@cs.wisc.edu#include <string>
2610447Snilay@cs.wisc.edu#include <cstdarg>
2710447Snilay@cs.wisc.edu#include <vector>
2810447Snilay@cs.wisc.edu#include <sstream>
2910447Snilay@cs.wisc.edu#include <bitset>
3010447Snilay@cs.wisc.edu
3110447Snilay@cs.wisc.edunamespace LibUtil
3210447Snilay@cs.wisc.edu{
3310447Snilay@cs.wisc.edu    using std::string;
3410447Snilay@cs.wisc.edu    using std::vector;
3510447Snilay@cs.wisc.edu
3610447Snilay@cs.wisc.edu    class String : public string
3710447Snilay@cs.wisc.edu    {
3810447Snilay@cs.wisc.edu        public:
3910447Snilay@cs.wisc.edu            static String format(const String& format_, ...);
4010447Snilay@cs.wisc.edu            static String format(const String& format_, va_list args_);
4110447Snilay@cs.wisc.edu            template<class T> static String toString(const T& value_);
4210447Snilay@cs.wisc.edu            static String toBitString(unsigned int value_, unsigned int num_bits_);
4310447Snilay@cs.wisc.edu            template<class T> static T fromString(const String& str_);
4410447Snilay@cs.wisc.edu
4510447Snilay@cs.wisc.edu        private:
4610447Snilay@cs.wisc.edu            static const unsigned int msBufferSize;
4710447Snilay@cs.wisc.edu
4810447Snilay@cs.wisc.edu        public:
4910447Snilay@cs.wisc.edu            String();
5010447Snilay@cs.wisc.edu            String(const string& str_);
5110447Snilay@cs.wisc.edu            String(const char* str_, size_t n);
5210447Snilay@cs.wisc.edu            String(const char* str_);
5310447Snilay@cs.wisc.edu            String(size_t n, char c);
5410447Snilay@cs.wisc.edu            String(int value_);
5510447Snilay@cs.wisc.edu            String(unsigned int value_);
5610447Snilay@cs.wisc.edu            String(long value_);
5710447Snilay@cs.wisc.edu            String(unsigned long value_);
5810447Snilay@cs.wisc.edu            String(float value_);
5910447Snilay@cs.wisc.edu            String(double value_);
6010447Snilay@cs.wisc.edu            String(bool value_);
6110447Snilay@cs.wisc.edu            ~String();
6210447Snilay@cs.wisc.edu
6310447Snilay@cs.wisc.edu        public:
6410447Snilay@cs.wisc.edu            // Remove leading and trailing whitespace
6510447Snilay@cs.wisc.edu            String& trim();
6610447Snilay@cs.wisc.edu            // Substitute str1 with str2
6710447Snilay@cs.wisc.edu            String& substitute(const String& str1_, const String& str2_);
6810447Snilay@cs.wisc.edu            // Split the String into vector of Strings separated by delimiters_
6910447Snilay@cs.wisc.edu            vector<String> split(const char* delimiters_) const;
7010447Snilay@cs.wisc.edu            vector<String> split(const String* delimiters_, unsigned int num_delimiters_ = 1) const;
7110447Snilay@cs.wisc.edu            vector<String> splitByString(const String& delimiters_) const;
7210447Snilay@cs.wisc.edu
7310447Snilay@cs.wisc.edu            // Check if contains str
7410447Snilay@cs.wisc.edu            bool contain(const String& str_) const;
7510447Snilay@cs.wisc.edu
7610447Snilay@cs.wisc.edu        public:
7710447Snilay@cs.wisc.edu            // Convertions
7810447Snilay@cs.wisc.edu            const char* toCString() const;
7910447Snilay@cs.wisc.edu            int toInt() const;
8010447Snilay@cs.wisc.edu            unsigned int toUInt() const;
8110447Snilay@cs.wisc.edu            long toLong() const;
8210447Snilay@cs.wisc.edu            unsigned long toULong() const;
8310447Snilay@cs.wisc.edu            float toFloat() const;
8410447Snilay@cs.wisc.edu            double toDouble() const;
8510447Snilay@cs.wisc.edu            bool toBool() const;
8610447Snilay@cs.wisc.edu            operator const char*() const;
8710447Snilay@cs.wisc.edu            operator int() const;
8810447Snilay@cs.wisc.edu            operator unsigned int() const;
8910447Snilay@cs.wisc.edu            operator long() const;
9010447Snilay@cs.wisc.edu            operator unsigned long() const;
9110447Snilay@cs.wisc.edu            operator float() const;
9210447Snilay@cs.wisc.edu            operator double() const;
9310447Snilay@cs.wisc.edu            operator bool() const;
9410447Snilay@cs.wisc.edu            String& operator=(char c_);
9510447Snilay@cs.wisc.edu    };
9610447Snilay@cs.wisc.edu
9710447Snilay@cs.wisc.edu    template<class T> String String::toString(const T& value_)
9810447Snilay@cs.wisc.edu    {
9910447Snilay@cs.wisc.edu        std::ostringstream ost;
10010447Snilay@cs.wisc.edu        ost << value_;
10110447Snilay@cs.wisc.edu        return ost.str();
10210447Snilay@cs.wisc.edu    }
10310447Snilay@cs.wisc.edu
10410447Snilay@cs.wisc.edu    template<> inline String String::toString<bool>(const bool& value_)
10510447Snilay@cs.wisc.edu    {
10610447Snilay@cs.wisc.edu        if(value_ == true)
10710447Snilay@cs.wisc.edu        {
10810447Snilay@cs.wisc.edu            return "TRUE";
10910447Snilay@cs.wisc.edu        }
11010447Snilay@cs.wisc.edu        else
11110447Snilay@cs.wisc.edu        {
11210447Snilay@cs.wisc.edu            return "FALSE";
11310447Snilay@cs.wisc.edu        }
11410447Snilay@cs.wisc.edu    }
11510447Snilay@cs.wisc.edu
11610447Snilay@cs.wisc.edu    inline String String::toBitString(unsigned int value_, unsigned int num_bits_)
11710447Snilay@cs.wisc.edu    {
11810447Snilay@cs.wisc.edu        std::bitset<sizeof(unsigned int)*8> bitSet(value_);
11910447Snilay@cs.wisc.edu        String ret = String(bitSet.to_string());
12010447Snilay@cs.wisc.edu        ret = ret.substr(ret.length()-num_bits_);
12110447Snilay@cs.wisc.edu        return ret;
12210447Snilay@cs.wisc.edu    }
12310447Snilay@cs.wisc.edu
12410447Snilay@cs.wisc.edu    template<class T> T String::fromString(const String& str_)
12510447Snilay@cs.wisc.edu    {
12610447Snilay@cs.wisc.edu        T ret;
12710447Snilay@cs.wisc.edu        std::istringstream ist(str_);
12810447Snilay@cs.wisc.edu        ist >> ret;
12910447Snilay@cs.wisc.edu        return ret;
13010447Snilay@cs.wisc.edu    }
13110447Snilay@cs.wisc.edu
13210447Snilay@cs.wisc.edu    template<> inline String String::fromString<String>(const String& str_)
13310447Snilay@cs.wisc.edu    {
13410447Snilay@cs.wisc.edu        return str_;
13510447Snilay@cs.wisc.edu    }
13610447Snilay@cs.wisc.edu
13710447Snilay@cs.wisc.edu    template<> inline bool String::fromString<bool>(const String& str_)
13810447Snilay@cs.wisc.edu    {
13910447Snilay@cs.wisc.edu        bool ret;
14010447Snilay@cs.wisc.edu        if((str_ == String("TRUE")) || (str_ == String("true")))
14110447Snilay@cs.wisc.edu        {
14210447Snilay@cs.wisc.edu            ret = true;
14310447Snilay@cs.wisc.edu        }
14410447Snilay@cs.wisc.edu        else if((str_ == string("FALSE")) || (str_ == String("false")))
14510447Snilay@cs.wisc.edu        {
14610447Snilay@cs.wisc.edu            ret = false;
14710447Snilay@cs.wisc.edu        }
14810447Snilay@cs.wisc.edu        else
14910447Snilay@cs.wisc.edu        {
15010447Snilay@cs.wisc.edu            //std::cerr << "Invalid bool value: " << str_ << std::endl;
15110447Snilay@cs.wisc.edu            throw ("Invalid bool value: " + str_);
15210447Snilay@cs.wisc.edu        }
15310447Snilay@cs.wisc.edu        return ret;
15410447Snilay@cs.wisc.edu    }
15510447Snilay@cs.wisc.edu
15610447Snilay@cs.wisc.edu    template<class T> String arrayToString(
15710447Snilay@cs.wisc.edu            const T* array_, unsigned int start_index_, unsigned int end_index_,
15810447Snilay@cs.wisc.edu            const String& delimiters_
15910447Snilay@cs.wisc.edu            )
16010447Snilay@cs.wisc.edu    {
16110447Snilay@cs.wisc.edu        // Ensure end_index_ >= start_index_ + 1
16210447Snilay@cs.wisc.edu        if(end_index_ <= start_index_)
16310447Snilay@cs.wisc.edu        {
16410447Snilay@cs.wisc.edu            throw("Invalid index range: start_index = " + (String)start_index_ + ", end_index = " + (String)end_index_);
16510447Snilay@cs.wisc.edu        }
16610447Snilay@cs.wisc.edu
16710447Snilay@cs.wisc.edu        String ret = "[";
16810447Snilay@cs.wisc.edu        for(unsigned int i = start_index_; i < (end_index_-1); ++i)
16910447Snilay@cs.wisc.edu        {
17010447Snilay@cs.wisc.edu            ret += (String)array_[i] + delimiters_;
17110447Snilay@cs.wisc.edu        }
17210447Snilay@cs.wisc.edu        ret += (String)array_[end_index_-1] + "]";
17310447Snilay@cs.wisc.edu        return ret;
17410447Snilay@cs.wisc.edu    }
17510447Snilay@cs.wisc.edu
17610447Snilay@cs.wisc.edu    template<class T> String arrayToString(const T* array_, unsigned int num_elements_)
17710447Snilay@cs.wisc.edu    {
17810447Snilay@cs.wisc.edu        return arrayToString(array_, 0, num_elements_, ", ");
17910447Snilay@cs.wisc.edu    }
18010447Snilay@cs.wisc.edu
18110447Snilay@cs.wisc.edu    template<class T> String arrayToString(const T* array_, unsigned int start_index_, unsigned int end_index_)
18210447Snilay@cs.wisc.edu    {
18310447Snilay@cs.wisc.edu        return arrayToString(array_, start_index_, end_index_);
18410447Snilay@cs.wisc.edu    }
18510447Snilay@cs.wisc.edu
18610447Snilay@cs.wisc.edu    template<class T> String vectorToString(
18710447Snilay@cs.wisc.edu        const vector<T>& vector_, unsigned int start_index_, unsigned int end_index_,
18810447Snilay@cs.wisc.edu        const String& delimiters_
18910447Snilay@cs.wisc.edu        )
19010447Snilay@cs.wisc.edu    {
19110447Snilay@cs.wisc.edu        // Ensure end_index_ >= start_index_ + 1, or if the vector is empty
19210447Snilay@cs.wisc.edu        if((end_index_ <= start_index_) || (end_index_ > vector_.size()))
19310447Snilay@cs.wisc.edu        {
19410447Snilay@cs.wisc.edu            // If the vector is empty, return empty array
19510447Snilay@cs.wisc.edu            if (vector_.size() == 0)
19610447Snilay@cs.wisc.edu                return "[]";
19710447Snilay@cs.wisc.edu
19810447Snilay@cs.wisc.edu            throw("Invalid index range: start_index = " + (String)start_index_ + ", end_index = " + (String)end_index_);
19910447Snilay@cs.wisc.edu        }
20010447Snilay@cs.wisc.edu
20110447Snilay@cs.wisc.edu        String ret = "[";
20210447Snilay@cs.wisc.edu        for(unsigned int i = start_index_; i < (end_index_-1); ++i)
20310447Snilay@cs.wisc.edu        {
20410447Snilay@cs.wisc.edu            ret += (String)vector_[i] + delimiters_;
20510447Snilay@cs.wisc.edu        }
20610447Snilay@cs.wisc.edu        ret += (String)vector_[end_index_-1] + "]";
20710447Snilay@cs.wisc.edu        return ret;
20810447Snilay@cs.wisc.edu    }
20910447Snilay@cs.wisc.edu
21010447Snilay@cs.wisc.edu    template<class T> String vectorToString(const vector<T>& vector_)
21110447Snilay@cs.wisc.edu    {
21210447Snilay@cs.wisc.edu        return vectorToString(vector_, 0, vector_.size(), ", ");
21310447Snilay@cs.wisc.edu    }
21410447Snilay@cs.wisc.edu
21510447Snilay@cs.wisc.edu    template<class T> String vectorToString(const vector<T>& vector_, unsigned int num_elements_)
21610447Snilay@cs.wisc.edu    {
21710447Snilay@cs.wisc.edu        return vectorToString(vector_, 0, num_elements_, ", ");
21810447Snilay@cs.wisc.edu    }
21910447Snilay@cs.wisc.edu
22010447Snilay@cs.wisc.edu    template<class T> String vectorToString(const vector<T>& vector_, unsigned int start_index_, unsigned int end_index_)
22110447Snilay@cs.wisc.edu    {
22210447Snilay@cs.wisc.edu        return vectorToString(vector_, start_index_, end_index_);
22310447Snilay@cs.wisc.edu    }
22410447Snilay@cs.wisc.edu
22510447Snilay@cs.wisc.edu    template<class T> vector<T> castStringVector(const vector<String>& vector_)
22610447Snilay@cs.wisc.edu    {
22710447Snilay@cs.wisc.edu        vector<T> ret_vector;
22810447Snilay@cs.wisc.edu        for(unsigned int i = 0; i < vector_.size(); ++i)
22910447Snilay@cs.wisc.edu        {
23010447Snilay@cs.wisc.edu            ret_vector.push_back((T)vector_[i]);
23110447Snilay@cs.wisc.edu        }
23210447Snilay@cs.wisc.edu        return ret_vector;
23310447Snilay@cs.wisc.edu    }
23410447Snilay@cs.wisc.edu
23510447Snilay@cs.wisc.edu    std::istream& safeGetline(std::istream& is_, String& str_);
23610447Snilay@cs.wisc.edu} // namespace LibUtil
23710447Snilay@cs.wisc.edu
23810447Snilay@cs.wisc.edu#endif // __STRING_H__
23910447Snilay@cs.wisc.edu
240