`
zhangyafei_kimi
  • 浏览: 261649 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

boost.lexical_cast源码整理和使用说明

阅读更多

Source

#include <cstddef>

#include <string>

#include <typeinfo>

//#include <boost/config.hpp>

#include <boost/limits.hpp>

#include <boost/throw_exception.hpp>

#include <boost/type_traits/is_pointer.hpp>

#include <sstream>

//

namespace kimi_boost

{

// exception used to indicate runtime lexical_cast failure

class bad_lexical_cast : public std::bad_cast

{

public:

bad_lexical_cast() :

source(&typeid(void)), target(&typeid(void))

{

}

bad_lexical_cast(

const std::type_info &source_type,

const std::type_info &target_type) :

source(&source_type), target(&target_type)

{

}

const std::type_info &source_type() const

{

return *source;

}

const std::type_info &target_type() const

{

return *target;

}

virtual const char *what() const throw()

{

return "bad lexical cast: "

"source type value could not be interpreted as target";

}

virtual ~bad_lexical_cast() throw()

{

}

private:

const std::type_info *source;

const std::type_info *target;

};

namespace detail // stream wrapper for handling lexical conversions

{

template<typename Target, typename Source>

class lexical_stream

{

private:

typedef char char_type;

std::basic_stringstream<char_type> stream;

public:

lexical_stream()

{

stream.unsetf(std::ios::skipws);

if(std::numeric_limits<Target>::is_specialized)

stream.precision(std::numeric_limits<Target>::digits10 + 1);

else if(std::numeric_limits<Source>::is_specialized)

stream.precision(std::numeric_limits<Source>::digits10 + 1);

}

~lexical_stream()

{

}

//Source类型输入到流中

bool operator<<(const Source &input)

{

return !(stream << input).fail();

}

//把流转换为Target类型输出

template<typename InputStreamable>

bool operator>>(InputStreamable &output)

{

return !boost::is_pointer<InputStreamable>::value &&

stream >> output &&

stream.get() ==

std::char_traits<char_type>::eof();

}

//string特化

template<>

bool operator>>(std::string &output)

{

output = stream.str();

return true;

}

};//class lexical_stream

}//namespace detail

namespace detail

{

template<class T>

struct array_to_pointer_decay

{

typedef T type;

};

template<class T, std::size_t N>

struct array_to_pointer_decay<T[N]>

{

typedef const T * type;

};

}

template<typename Target, typename Source>

Target lexical_cast(const Source &arg)

{

typedef typename detail::array_to_pointer_decay<Source>::type NewSource;

detail::lexical_stream<Target, NewSource> interpreter;

Target result;

if(!(interpreter << arg && interpreter >> result))

boost::throw_exception(bad_lexical_cast(typeid(NewSource), typeid(Target)));

return result;

}

}

Test code

void kimi_lexical_cast_test()

{

try

{

int i=kimi_boost::lexical_cast<int>("4365");

float f=kimi_boost::lexical_cast<float>("234.546");

double d=kimi_boost::lexical_cast<double>("24534.546345");

std::string s=kimi_boost::lexical_cast<std::string>(24534.546345);

}

catch(kimi_boost::bad_lexical_cast& e)

{

cout<<e.what()<<endl;

}

try{

int i2=kimi_boost::lexical_cast<int>("0.335");

}

catch(kimi_boost::bad_lexical_cast& e)

{

cout<<"source type: "<<e.source_type().name()<<endl;

cout<<"target type: "<<e.target_type().name()<<endl;

cout<<e.what()<<endl;

}

}

Output

source type: char const *

target type: int

bad lexical cast: source type value could not be interpreted as target

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics