Files
armadillo-code/include/armadillo_bits/arma_str.hpp
T
2021-09-21 14:18:36 +10:00

523 lines
10 KiB
C++

// 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 format
{
public:
format(const char* in_fmt)
: A(in_fmt)
{
}
format(const std::string& in_fmt)
: A(in_fmt)
{
}
// TODO: constructor to handle std::string&& ?
const std::string A;
private:
format();
};
template<typename T1, typename T2>
class basic_format
{
public:
basic_format(const T1& in_A, const T2& in_B)
: A(in_A)
, B(in_B)
{
}
const T1& A;
const T2& 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)
{
char local_buffer[1024];
char* buffer = local_buffer;
int buffer_size = 1024;
int required_size = buffer_size;
bool using_local_buffer = true;
std::string out;
do
{
if(using_local_buffer == false)
{
buffer = new char[size_t(buffer_size)];
}
required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.c_str(), X.B);
if(required_size < 0) { break; }
if(required_size < buffer_size)
{
if(required_size > 0)
{
out = buffer;
}
}
else
{
buffer_size *= 2;
}
if(using_local_buffer)
{
using_local_buffer = false;
}
else
{
delete[] buffer;
}
} while( (required_size >= buffer_size) );
return out;
}
template<typename T2, typename T3>
inline
std::string
str(const basic_format< basic_format< format, T2>, T3>& X)
{
char local_buffer[1024];
char* buffer = local_buffer;
int buffer_size = 1024;
int required_size = buffer_size;
bool using_local_buffer = true;
std::string out;
do
{
if(using_local_buffer == false)
{
buffer = new char[size_t(buffer_size)];
}
required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.A.c_str(), X.A.B, X.B);
if(required_size < 0) { break; }
if(required_size < buffer_size)
{
if(required_size > 0)
{
out = buffer;
}
}
else
{
buffer_size *= 2;
}
if(using_local_buffer)
{
using_local_buffer = false;
}
else
{
delete[] buffer;
}
} while( (required_size >= buffer_size) );
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 local_buffer[1024];
char* buffer = local_buffer;
int buffer_size = 1024;
int required_size = buffer_size;
bool using_local_buffer = true;
std::string out;
do
{
if(using_local_buffer == false)
{
buffer = new char[size_t(buffer_size)];
}
required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.A.A.c_str(), X.A.A.B, X.A.B, X.B);
if(required_size < 0) { break; }
if(required_size < buffer_size)
{
if(required_size > 0)
{
out = buffer;
}
}
else
{
buffer_size *= 2;
}
if(using_local_buffer)
{
using_local_buffer = false;
}
else
{
delete[] buffer;
}
} while( (required_size >= buffer_size) );
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 local_buffer[1024];
char* buffer = local_buffer;
int buffer_size = 1024;
int required_size = buffer_size;
bool using_local_buffer = true;
std::string out;
do
{
if(using_local_buffer == false)
{
buffer = new char[size_t(buffer_size)];
}
required_size = std::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);
if(required_size < 0) { break; }
if(required_size < buffer_size)
{
if(required_size > 0)
{
out = buffer;
}
}
else
{
buffer_size *= 2;
}
if(using_local_buffer)
{
using_local_buffer = false;
}
else
{
delete[] buffer;
}
} while( (required_size >= buffer_size) );
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 local_buffer[1024];
char* buffer = local_buffer;
int buffer_size = 1024;
int required_size = buffer_size;
bool using_local_buffer = true;
std::string out;
do
{
if(using_local_buffer == false)
{
buffer = new char[size_t(buffer_size)];
}
required_size = std::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);
if(required_size < 0) { break; }
if(required_size < buffer_size)
{
if(required_size > 0)
{
out = buffer;
}
}
else
{
buffer_size *= 2;
}
if(using_local_buffer)
{
using_local_buffer = false;
}
else
{
delete[] buffer;
}
} while( (required_size >= buffer_size) );
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 local_buffer[1024];
char* buffer = local_buffer;
int buffer_size = 1024;
int required_size = buffer_size;
bool using_local_buffer = true;
std::string out;
do
{
if(using_local_buffer == false)
{
buffer = new char[size_t(buffer_size)];
}
required_size = std::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);
if(required_size < 0) { break; }
if(required_size < buffer_size)
{
if(required_size > 0)
{
out = buffer;
}
}
else
{
buffer_size *= 2;
}
if(using_local_buffer)
{
using_local_buffer = false;
}
else
{
delete[] buffer;
}
} while( (required_size >= buffer_size) );
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);
}
}
//! @}