summaryrefslogtreecommitdiffstats
path: root/src/armadillo/include/armadillo_bits/arma_str.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/armadillo/include/armadillo_bits/arma_str.hpp')
-rw-r--r--src/armadillo/include/armadillo_bits/arma_str.hpp437
1 files changed, 437 insertions, 0 deletions
diff --git a/src/armadillo/include/armadillo_bits/arma_str.hpp b/src/armadillo/include/armadillo_bits/arma_str.hpp
new file mode 100644
index 0000000..29f84a6
--- /dev/null
+++ b/src/armadillo/include/armadillo_bits/arma_str.hpp
@@ -0,0 +1,437 @@
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
+// Copyright 2008-2016 National ICT Australia (NICTA)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ------------------------------------------------------------------------
+
+
+//! \addtogroup arma_str
+//! @{
+
+
+namespace arma_str
+ {
+ class char_buffer
+ {
+ public:
+
+ static constexpr uword n_chars_prealloc = 1024;
+
+ char* mem = nullptr;
+ uword n_chars = 0;
+
+ char local_mem[n_chars_prealloc];
+
+ inline
+ ~char_buffer()
+ {
+ if(n_chars > n_chars_prealloc) { std::free(mem); }
+
+ mem = nullptr;
+ n_chars = 0;
+ }
+
+ inline
+ char_buffer()
+ {
+ mem = &(local_mem[0]);
+ n_chars = n_chars_prealloc;
+
+ if(n_chars > 0) { mem[0] = char(0); }
+ }
+
+ inline
+ void
+ set_size(const uword new_n_chars)
+ {
+ if(n_chars > n_chars_prealloc) { std::free(mem); }
+
+ mem = (new_n_chars <= n_chars_prealloc) ? &(local_mem[0]) : (char*)std::malloc(new_n_chars);
+ n_chars = (new_n_chars <= n_chars_prealloc) ? n_chars_prealloc : new_n_chars;
+
+ if(n_chars > 0) { mem[0] = char(0); }
+ }
+ };
+
+
+ class format
+ {
+ public:
+
+ const std::string fmt;
+
+ inline format(const char* in_fmt) : fmt(in_fmt) { }
+ inline format(const std::string& in_fmt) : fmt(in_fmt) { }
+
+ private:
+ format();
+ };
+
+
+
+ template<typename T1, typename T2>
+ class basic_format
+ {
+ public:
+
+ const T1& A;
+ const T2& B;
+
+ inline basic_format(const T1& in_A, const T2& in_B) : A(in_A) , B(in_B) { }
+
+ private:
+ basic_format();
+ };
+
+
+
+ template<typename T2>
+ inline
+ basic_format< format, T2 >
+ operator% (const format& X, const T2& arg)
+ {
+ return basic_format< format, T2 >(X, arg);
+ }
+
+
+
+ template<typename T1, typename T2, typename T3>
+ inline
+ basic_format< basic_format<T1,T2>, T3 >
+ operator% (const basic_format<T1,T2>& X, const T3& arg)
+ {
+ return basic_format< basic_format<T1,T2>, T3 >(X, arg);
+ }
+
+
+
+ template<typename T2>
+ inline
+ std::string
+ str(const basic_format< format, T2>& X)
+ {
+ std::string out;
+ char_buffer buf;
+
+ bool status = false;
+
+ while(status == false)
+ {
+ int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.fmt.c_str(), X.B);
+
+ if(required_size < 0) { break; }
+
+ if(uword(required_size) >= buf.n_chars)
+ {
+ if(buf.n_chars > char_buffer::n_chars_prealloc) { break; }
+
+ buf.set_size(1 + uword(required_size));
+ }
+ else
+ {
+ status = true;
+ }
+
+ if(status) { out = buf.mem; }
+ }
+
+ return out;
+ }
+
+
+
+ template<typename T2, typename T3>
+ inline
+ std::string
+ str(const basic_format< basic_format< format, T2>, T3>& X)
+ {
+ char_buffer buf;
+ std::string out;
+
+ bool status = false;
+
+ while(status == false)
+ {
+ int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.A.fmt.c_str(), X.A.B, X.B);
+
+ if(required_size < 0) { break; }
+
+ if(uword(required_size) >= buf.n_chars)
+ {
+ if(buf.n_chars > char_buffer::n_chars_prealloc) { break; }
+
+ buf.set_size(1 + uword(required_size));
+ }
+ else
+ {
+ status = true;
+ }
+
+ if(status) { out = buf.mem; }
+ }
+
+ return out;
+ }
+
+
+
+ template<typename T2, typename T3, typename T4>
+ inline
+ std::string
+ str(const basic_format< basic_format< basic_format< format, T2>, T3>, T4>& X)
+ {
+ char_buffer buf;
+ std::string out;
+
+ bool status = false;
+
+ while(status == false)
+ {
+ int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.A.A.fmt.c_str(), X.A.A.B, X.A.B, X.B);
+
+ if(required_size < 0) { break; }
+
+ if(uword(required_size) >= buf.n_chars)
+ {
+ if(buf.n_chars > char_buffer::n_chars_prealloc) { break; }
+
+ buf.set_size(1 + uword(required_size));
+ }
+ else
+ {
+ status = true;
+ }
+
+ if(status) { out = buf.mem; }
+ }
+
+ return out;
+ }
+
+
+
+ template<typename T2, typename T3, typename T4, typename T5>
+ inline
+ std::string
+ str(const basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>& X)
+ {
+ char_buffer buf;
+ std::string out;
+
+ bool status = false;
+
+ while(status == false)
+ {
+ int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.A.A.A.fmt.c_str(), X.A.A.A.B, X.A.A.B, X.A.B, X.B);
+
+ if(required_size < 0) { break; }
+
+ if(uword(required_size) >= buf.n_chars)
+ {
+ if(buf.n_chars > char_buffer::n_chars_prealloc) { break; }
+
+ buf.set_size(1 + uword(required_size));
+ }
+ else
+ {
+ status = true;
+ }
+
+ if(status) { out = buf.mem; }
+ }
+
+ return out;
+ }
+
+
+
+ template<typename T2, typename T3, typename T4, typename T5, typename T6>
+ inline
+ std::string
+ str(const basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>& X)
+ {
+ char_buffer buf;
+ std::string out;
+
+ bool status = false;
+
+ while(status == false)
+ {
+ int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.A.A.A.A.fmt.c_str(), X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B);
+
+ if(required_size < 0) { break; }
+
+ if(uword(required_size) >= buf.n_chars)
+ {
+ if(buf.n_chars > char_buffer::n_chars_prealloc) { break; }
+
+ buf.set_size(1 + uword(required_size));
+ }
+ else
+ {
+ status = true;
+ }
+
+ if(status) { out = buf.mem; }
+ }
+
+ return out;
+ }
+
+
+
+ template<typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
+ inline
+ std::string
+ str(const basic_format< basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>, T7>& X)
+ {
+ char_buffer buf;
+ std::string out;
+
+ bool status = false;
+
+ while(status == false)
+ {
+ int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.A.A.A.A.A.fmt.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);
+
+ if(required_size < 0) { break; }
+
+ if(uword(required_size) >= buf.n_chars)
+ {
+ if(buf.n_chars > char_buffer::n_chars_prealloc) { break; }
+
+ buf.set_size(1 + uword(required_size));
+ }
+ else
+ {
+ status = true;
+ }
+
+ if(status) { out = buf.mem; }
+ }
+
+ return out;
+ }
+
+
+
+ template<typename T1>
+ struct format_metaprog
+ {
+ static constexpr uword depth = 0;
+
+ inline
+ static
+ const std::string&
+ get_fmt(const T1& X)
+ {
+ return X.A;
+ }
+ };
+
+
+
+ //template<>
+ template<typename T1, typename T2>
+ struct format_metaprog< basic_format<T1,T2> >
+ {
+ static constexpr uword depth = 1 + format_metaprog<T1>::depth;
+
+ inline
+ static
+ const std::string&
+ get_fmt(const T1& X)
+ {
+ return format_metaprog<T1>::get_fmt(X.A);
+ }
+
+ };
+
+
+
+ template<typename T1, typename T2>
+ inline
+ std::string
+ str(const basic_format<T1,T2>& X)
+ {
+ return format_metaprog< basic_format<T1,T2> >::get_fmt(X.A);
+ }
+
+
+
+ template<typename T1, typename T2>
+ inline
+ std::ostream&
+ operator<< (std::ostream& o, const basic_format<T1,T2>& X)
+ {
+ o << str(X);
+ return o;
+ }
+
+
+ template<typename T> struct string_only { };
+ template<> struct string_only<std::string> { typedef std::string result; };
+
+ template<typename T> struct char_only { };
+ template<> struct char_only<char > { typedef char result; };
+
+ template<typename T>
+ struct basic_format_only { };
+
+ template<typename T1, typename T2>
+ struct basic_format_only< basic_format<T1, T2> > { typedef basic_format<T1,T2> result; };
+
+
+
+ template<typename T1>
+ inline
+ static
+ const T1&
+ str_wrapper(const T1& x, const typename string_only<T1>::result* junk = nullptr)
+ {
+ arma_ignore(junk);
+
+ return x;
+ }
+
+
+
+ template<typename T1>
+ inline
+ static
+ const T1*
+ str_wrapper(const T1* x, const typename char_only<T1>::result* junk = nullptr)
+ {
+ arma_ignore(junk);
+
+ return x;
+ }
+
+
+
+ template<typename T1>
+ inline
+ static
+ std::string
+ str_wrapper(const T1& x, const typename basic_format_only<T1>::result* junk = nullptr)
+ {
+ arma_ignore(junk);
+
+ return str(x);
+ }
+
+ }
+
+
+//! @}