#include <stdexcept>
#include <string>
#include <sstream>
#include <iostream>
#include <limits>

template<class T>
std::wstring ToString(T input)
{
    std::wostringstream ss;
    ss.precision(std::numeric_limits<T>::digits10);
    ss << input;
    if (!ss.good())
    {
        //Raise your favorite exception.
        throw std::runtime_error("Invalid input.");
    }
    return std::wstring(ss.str());
}

template<class T>
T FromString(const wchar_t *input)
{
    std::wistringstream ss(input);
    ss.precision(std::numeric_limits<T>::digits10);
    T output;
    ss >> output;
    if (ss.fail() || !ss.eof())
    {
        //Raise your favorite exception.
        throw std::runtime_error("Invalid input.");
    }
    return output;
}

template<class T>
T FromString(const std::wstring &input)
{
    return FromString<T>(input.c_str());
}

std::wstring operator+(const wchar_t *op1, const std::wstring &op2)
{
    return std::wstring(op1) + op2;
}

int main()
{
    double pi = 3.14159265359;
    std::wcout.precision(std::numeric_limits<double>::digits10);
    std::wcout << L"PI is " + ToString(pi) << std::endl;
    const wchar_t *strPi = L"3.14159265359";
    double newPi = FromString<double>(strPi);
    std::wcout << newPi << std::endl;
    const wchar_t *strPi2 = L"3,14159265359";
    try
    {
        double newPi2 = FromString<double>(strPi2);
        std::wcout << newPi2 << std::endl;
    }
    catch (std::exception &ex)
    {
        std::wcout << L"Exception occurred:  " << ex.what() << std::endl;
    }
    double newPi3 = FromString<double>(std::wstring(strPi));
    std::wcout << newPi3 << std::endl;
    return 0;
}
