/*
 * Copyright (c) 2001-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 */

#ifndef __BASE_STR_HH__
#define __BASE_STR_HH__

#include <cstring>
#include <limits>
#include <locale>
#include <stdexcept>
#include <string>
#include <vector>

inline void
eat_lead_white(std::string &s)
{
    std::string::size_type off = s.find_first_not_of(' ');
    if (off != std::string::npos) {
        std::string::iterator begin = s.begin();
        s.erase(begin, begin + off);
    }
}

inline void
eat_end_white(std::string &s)
{
    std::string::size_type off = s.find_last_not_of(' ');
    if (off != std::string::npos)
        s.erase(s.begin() + off + 1, s.end());
}

inline void
eat_white(std::string &s)
{
    eat_lead_white(s);
    eat_end_white(s);
}

inline std::string
to_lower(const std::string &s)
{
    std::string lower;
    int len = s.size();

    lower.reserve(len);

    for (const auto &c : s)
        lower.push_back(std::tolower(c));

    return lower;
}

// Split the string s into lhs and rhs on the first occurence of the
// character c.
bool
split_first(const std::string &s, std::string &lhs, std::string &rhs, char c);

// Split the string s into lhs and rhs on the last occurence of the
// character c.
bool
split_last(const std::string &s, std::string &lhs, std::string &rhs, char c);

// Tokenize the string <s> splitting on the character <token>, and
// place the result in the string vector <vector>.  If <ign> is true,
// then empty result strings (due to trailing tokens, or consecutive
// tokens) are skipped.
void
tokenize(std::vector<std::string> &vector, const std::string &s,
         char token, bool ign = true);

/**
 * @{
 *
 * @name String to number helper functions for signed and unsigned
 *       integeral type, as well as floating-point types.
 */
template <class T>
typename std::enable_if<std::is_integral<T>::value &&
                        std::is_signed<T>::value, T>::type
__to_number(const std::string &value)
{
    // start big and narrow it down if needed, determine the base dynamically
    long long r = std::stoll(value, nullptr, 0);
    if (r < std::numeric_limits<T>::min() || r > std::numeric_limits<T>::max())
        throw std::out_of_range("Out of range");
    return static_cast<T>(r);
}

template <class T>
typename std::enable_if<std::is_integral<T>::value &&
                        !std::is_signed<T>::value, T>::type
__to_number(const std::string &value)
{
    // start big and narrow it down if needed, determine the base dynamically
    unsigned long long r = std::stoull(value, nullptr, 0);
    if (r > std::numeric_limits<T>::max())
        throw std::out_of_range("Out of range");
    return static_cast<T>(r);
}

template <class T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
__to_number(const std::string &value)
{
    // start big and narrow it down if needed
    long double r = std::stold(value);
    if (r < std::numeric_limits<T>::min() || r > std::numeric_limits<T>::max())
        throw std::out_of_range("Out of range");
    return static_cast<T>(r);
}
/** @} */

/**
 * Turn a string representation of a number, either integral or
 * floating point, into an actual number.
 *
 * @param value The string representing the number
 * @param retval The resulting value
 * @return True if the parsing was successful
 */
template <class T>
inline bool
to_number(const std::string &value, T &retval)
{
    try {
        retval = __to_number<T>(value);
        return true;
    } catch (const std::out_of_range&) {
        return false;
    } catch (const std::invalid_argument&) {
        return false;
    }
}

/**
 * Turn a string representation of a boolean into a boolean value.
 */
inline bool
to_bool(const std::string &value, bool &retval)
{
    std::string s = to_lower(value);

    if (s == "true") {
        retval = true;
        return true;
    } else if (s == "false") {
        retval = false;
        return true;
    }

    return false;
}

// Put quotes around string arg if it contains spaces.
inline std::string
quote(const std::string &s)
{
    std::string ret;
    bool quote = s.find(' ') != std::string::npos;

    if (quote)
        ret = '"';

    ret += s;

    if (quote)
        ret += '"';

    return ret;
}


/**
 * Return true if 's' starts with the prefix string 'prefix'.
 */
inline bool
startswith(const char *s, const char *prefix)
{
    return (strncmp(s, prefix, strlen(prefix)) == 0);
}


/**
 * Return true if 's' starts with the prefix string 'prefix'.
 */
inline bool
startswith(const std::string &s, const char *prefix)
{
    return (s.compare(0, strlen(prefix), prefix) == 0);
}


/**
 * Return true if 's' starts with the prefix string 'prefix'.
 */
inline bool
startswith(const std::string &s, const std::string &prefix)
{
    return (s.compare(0, prefix.size(), prefix) == 0);
}


#endif //__BASE_STR_HH__
