Chris@49: // Copyright (C) 2008-2010 NICTA (www.nicta.com.au) Chris@49: // Copyright (C) 2008-2010 Conrad Sanderson Chris@49: // Chris@49: // This Source Code Form is subject to the terms of the Mozilla Public Chris@49: // License, v. 2.0. If a copy of the MPL was not distributed with this Chris@49: // file, You can obtain one at http://mozilla.org/MPL/2.0/. Chris@49: Chris@49: Chris@49: //! \addtogroup format_wrap Chris@49: //! @{ Chris@49: Chris@49: Chris@49: //! \namespace arma_boost namespace for functions and classes which partially emulate Boost functionality Chris@49: namespace arma_boost Chris@49: { Chris@49: Chris@49: #if defined(ARMA_USE_BOOST_FORMAT) Chris@49: Chris@49: using boost::format; Chris@49: using boost::basic_format; Chris@49: using boost::str; Chris@49: Chris@49: #else Chris@49: Chris@49: #if defined(ARMA_HAVE_STD_SNPRINTF) Chris@49: Chris@49: #define arma_snprintf std::snprintf Chris@49: Chris@49: #else Chris@49: Chris@49: // better-than-nothing emulation of C99 snprintf(), Chris@49: // with correct return value and null-terminated output string. Chris@49: // note that _snprintf() provided by MS is not a good substitute for snprintf() Chris@49: Chris@49: inline Chris@49: int Chris@49: arma_snprintf(char* out, size_t size, const char* fmt, ...) Chris@49: { Chris@49: size_t i; Chris@49: Chris@49: for(i=0; i 0) Chris@49: out[size-1] = char(0); Chris@49: Chris@49: return int(i); Chris@49: } Chris@49: Chris@49: #endif Chris@49: Chris@49: class format Chris@49: { Chris@49: public: Chris@49: Chris@49: format(const char* in_fmt) Chris@49: : A(in_fmt) Chris@49: { Chris@49: } Chris@49: Chris@49: format(const std::string& in_fmt) Chris@49: : A(in_fmt) Chris@49: { Chris@49: } Chris@49: Chris@49: Chris@49: const std::string A; Chris@49: Chris@49: private: Chris@49: format(); Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: class basic_format Chris@49: { Chris@49: public: Chris@49: Chris@49: basic_format(const T1& in_A, const T2& in_B) Chris@49: : A(in_A) Chris@49: , B(in_B) Chris@49: { Chris@49: } Chris@49: Chris@49: const T1& A; Chris@49: const T2& B; Chris@49: Chris@49: private: Chris@49: basic_format(); Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: basic_format< format, T2 > Chris@49: operator% (const format& X, const T2& arg) Chris@49: { Chris@49: return basic_format< format, T2 >(X, arg); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: basic_format< basic_format, T3 > Chris@49: operator% (const basic_format& X, const T3& arg) Chris@49: { Chris@49: return basic_format< basic_format, T3 >(X, arg); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: std::string Chris@49: str(const basic_format< format, T2>& X) Chris@49: { Chris@49: char local_buffer[1024]; Chris@49: char* buffer = local_buffer; Chris@49: Chris@49: int buffer_size = 1024; Chris@49: int required_size = buffer_size; Chris@49: Chris@49: bool using_local_buffer = true; Chris@49: Chris@49: std::string out; Chris@49: Chris@49: do Chris@49: { Chris@49: if(using_local_buffer == false) Chris@49: { Chris@49: buffer = new char[buffer_size]; Chris@49: } Chris@49: Chris@49: required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.c_str(), X.B); Chris@49: Chris@49: if(required_size < buffer_size) Chris@49: { Chris@49: if(required_size > 0) Chris@49: { Chris@49: out = buffer; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: buffer_size *= 2; Chris@49: } Chris@49: Chris@49: if(using_local_buffer == true) Chris@49: { Chris@49: using_local_buffer = false; Chris@49: } Chris@49: else Chris@49: { Chris@49: delete[] buffer; Chris@49: } Chris@49: Chris@49: } while( (required_size >= buffer_size) ); Chris@49: Chris@49: return out; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: std::string Chris@49: str(const basic_format< basic_format< format, T2>, T3>& X) Chris@49: { Chris@49: char local_buffer[1024]; Chris@49: char* buffer = local_buffer; Chris@49: Chris@49: int buffer_size = 1024; Chris@49: int required_size = buffer_size; Chris@49: Chris@49: bool using_local_buffer = true; Chris@49: Chris@49: std::string out; Chris@49: Chris@49: do Chris@49: { Chris@49: if(using_local_buffer == false) Chris@49: { Chris@49: buffer = new char[buffer_size]; Chris@49: } Chris@49: Chris@49: required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.c_str(), X.A.B, X.B); Chris@49: Chris@49: if(required_size < buffer_size) Chris@49: { Chris@49: if(required_size > 0) Chris@49: { Chris@49: out = buffer; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: buffer_size *= 2; Chris@49: } Chris@49: Chris@49: if(using_local_buffer == true) Chris@49: { Chris@49: using_local_buffer = false; Chris@49: } Chris@49: else Chris@49: { Chris@49: delete[] buffer; Chris@49: } Chris@49: Chris@49: } while( (required_size >= buffer_size) ); Chris@49: Chris@49: return out; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: std::string Chris@49: str(const basic_format< basic_format< basic_format< format, T2>, T3>, T4>& X) Chris@49: { Chris@49: char local_buffer[1024]; Chris@49: char* buffer = local_buffer; Chris@49: Chris@49: int buffer_size = 1024; Chris@49: int required_size = buffer_size; Chris@49: Chris@49: bool using_local_buffer = true; Chris@49: Chris@49: std::string out; Chris@49: Chris@49: do Chris@49: { Chris@49: if(using_local_buffer == false) Chris@49: { Chris@49: buffer = new char[buffer_size]; Chris@49: } Chris@49: Chris@49: required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.c_str(), X.A.A.B, X.A.B, X.B); Chris@49: Chris@49: if(required_size < buffer_size) Chris@49: { Chris@49: if(required_size > 0) Chris@49: { Chris@49: out = buffer; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: buffer_size *= 2; Chris@49: } Chris@49: Chris@49: if(using_local_buffer == true) Chris@49: { Chris@49: using_local_buffer = false; Chris@49: } Chris@49: else Chris@49: { Chris@49: delete[] buffer; Chris@49: } Chris@49: Chris@49: } while( (required_size >= buffer_size) ); Chris@49: Chris@49: return out; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: std::string Chris@49: str(const basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>& X) Chris@49: { Chris@49: char local_buffer[1024]; Chris@49: char* buffer = local_buffer; Chris@49: Chris@49: int buffer_size = 1024; Chris@49: int required_size = buffer_size; Chris@49: Chris@49: bool using_local_buffer = true; Chris@49: Chris@49: std::string out; Chris@49: Chris@49: do Chris@49: { Chris@49: if(using_local_buffer == false) Chris@49: { Chris@49: buffer = new char[buffer_size]; Chris@49: } Chris@49: Chris@49: required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.c_str(), X.A.A.A.B, X.A.A.B, X.A.B, X.B); Chris@49: Chris@49: if(required_size < buffer_size) Chris@49: { Chris@49: if(required_size > 0) Chris@49: { Chris@49: out = buffer; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: buffer_size *= 2; Chris@49: } Chris@49: Chris@49: if(using_local_buffer == true) Chris@49: { Chris@49: using_local_buffer = false; Chris@49: } Chris@49: else Chris@49: { Chris@49: delete[] buffer; Chris@49: } Chris@49: Chris@49: } while( (required_size >= buffer_size) ); Chris@49: Chris@49: return out; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: std::string Chris@49: str(const basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>& X) Chris@49: { Chris@49: char local_buffer[1024]; Chris@49: char* buffer = local_buffer; Chris@49: Chris@49: int buffer_size = 1024; Chris@49: int required_size = buffer_size; Chris@49: Chris@49: bool using_local_buffer = true; Chris@49: Chris@49: std::string out; Chris@49: Chris@49: do Chris@49: { Chris@49: if(using_local_buffer == false) Chris@49: { Chris@49: buffer = new char[buffer_size]; Chris@49: } Chris@49: Chris@49: required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.c_str(), X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B); Chris@49: Chris@49: if(required_size < buffer_size) Chris@49: { Chris@49: if(required_size > 0) Chris@49: { Chris@49: out = buffer; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: buffer_size *= 2; Chris@49: } Chris@49: Chris@49: if(using_local_buffer == true) Chris@49: { Chris@49: using_local_buffer = false; Chris@49: } Chris@49: else Chris@49: { Chris@49: delete[] buffer; Chris@49: } Chris@49: Chris@49: } while( (required_size >= buffer_size) ); Chris@49: Chris@49: return out; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: std::string Chris@49: str(const basic_format< basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>, T7>& X) Chris@49: { Chris@49: char local_buffer[1024]; Chris@49: char* buffer = local_buffer; Chris@49: Chris@49: int buffer_size = 1024; Chris@49: int required_size = buffer_size; Chris@49: Chris@49: bool using_local_buffer = true; Chris@49: Chris@49: std::string out; Chris@49: Chris@49: do Chris@49: { Chris@49: if(using_local_buffer == false) Chris@49: { Chris@49: buffer = new char[buffer_size]; Chris@49: } Chris@49: Chris@49: required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.A.c_str(), X.A.A.A.A.A.B, X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B); Chris@49: Chris@49: if(required_size < buffer_size) Chris@49: { Chris@49: if(required_size > 0) Chris@49: { Chris@49: out = buffer; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: buffer_size *= 2; Chris@49: } Chris@49: Chris@49: if(using_local_buffer == true) Chris@49: { Chris@49: using_local_buffer = false; Chris@49: } Chris@49: else Chris@49: { Chris@49: delete[] buffer; Chris@49: } Chris@49: Chris@49: } while( (required_size >= buffer_size) ); Chris@49: Chris@49: return out; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct format_metaprog Chris@49: { Chris@49: static const uword depth = 0; Chris@49: Chris@49: inline Chris@49: static Chris@49: const std::string& Chris@49: get_fmt(const T1& X) Chris@49: { Chris@49: return X.A; Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: //template<> Chris@49: template Chris@49: struct format_metaprog< basic_format > Chris@49: { Chris@49: static const uword depth = 1 + format_metaprog::depth; Chris@49: Chris@49: inline Chris@49: static Chris@49: const std::string& Chris@49: get_fmt(const T1& X) Chris@49: { Chris@49: return format_metaprog::get_fmt(X.A); Chris@49: } Chris@49: Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: std::string Chris@49: str(const basic_format& X) Chris@49: { Chris@49: return format_metaprog< basic_format >::get_fmt(X.A); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: std::ostream& Chris@49: operator<< (std::ostream& o, const basic_format& X) Chris@49: { Chris@49: o << str(X); Chris@49: return o; Chris@49: } Chris@49: Chris@49: Chris@49: #endif Chris@49: Chris@49: Chris@49: template struct string_only { }; Chris@49: template<> struct string_only { typedef std::string result; }; Chris@49: Chris@49: template struct char_only { }; Chris@49: template<> struct char_only { typedef char result; }; Chris@49: Chris@49: template Chris@49: struct basic_format_only { }; Chris@49: Chris@49: #if defined(ARMA_USE_BOOST_FORMAT) Chris@49: template Chris@49: struct basic_format_only< basic_format > { typedef basic_format result; }; Chris@49: #else Chris@49: template Chris@49: struct basic_format_only< basic_format > { typedef basic_format result; }; Chris@49: #endif Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: static Chris@49: const T1& Chris@49: str_wrapper(const T1& x, const typename string_only::result* junk = 0) Chris@49: { Chris@49: arma_ignore(junk); Chris@49: Chris@49: return x; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: static Chris@49: const T1* Chris@49: str_wrapper(const T1* x, const typename char_only::result* junk = 0) Chris@49: { Chris@49: arma_ignore(junk); Chris@49: Chris@49: return x; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: static Chris@49: std::string Chris@49: str_wrapper(const T1& x, const typename basic_format_only::result* junk = 0) Chris@49: { Chris@49: arma_ignore(junk); Chris@49: Chris@49: return str(x); Chris@49: } Chris@49: Chris@49: } Chris@49: Chris@49: //! @}