如何从 boost karma 生成 C++ 数组?
How does one generate from boost karma into C++ array?
我了解如何使用业力生成管理内存的容器,例如 std::string。但是如果缓冲区 (char[N]) 已经被预分配了呢?
{
using namespace boost::spirit::karma;
{
std::string buffer;
generate(std::inserter(buffer, buffer.begin()), double_, 3.13);
std::cout << ':' << buffer << ':' << std::endl;
}
{
//////////////////////////////////////////////////////////////////////
// How to make the following work? Is there a builtin output
// iterator that just works?
#if defined(MAJIC)
char buffer[1024];
generate(buffer, double_, 3.13);
std::cout << ':' << buffer << ':' << std::endl;
#endif
}
}
我想找到一种方法将双精度解析为现有缓冲区的地址。可以假设缓冲区对于这种情况足够大。也许潜在的问题真的是——是否已经有一个输出迭代器适配器或 karma 中可以使用的原生数组?
基于 Karma 迭代器的 API (here) 采用...输出迭代器。
你可以只为你的数组创建一个。
问题在于您需要非常确定缓冲区容量永远不会不足:
char buffer[1024];
char* it = buffer;
karma::generate(it, karma::double_ << karma::eol, 3.13);
std::cout.write(buffer, std::distance(buffer, it));
请注意,您不能假定缓冲区以 NUL 结尾。使用生成的大小。
安全使用 array_sink
:
Boost Iostreams 中有一种更方便、更通用的方法,它在面对固定大小的缓冲区时也是安全的:
char buffer[310];
io::stream<io::array_sink> as(buffer);
boost::spirit::ostream_iterator it(as);
这里有一个演示特性的现场演示:
#include <boost/spirit/include/karma.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
namespace karma = boost::spirit::karma;
namespace io = boost::iostreams;
void test(std::vector<int> const& v)
{
char buffer[310];
io::stream<io::array_sink> as(buffer);
boost::spirit::ostream_iterator it(as);
using namespace karma;
if (generate(it, int_ % ", " << eol, v))
{
std::cout << "Success: ";
std::cout.write(buffer, as.tellp());
} else
std::cout << "Generation failed (insufficient capacity?)\n";
}
int main() {
std::cout << "Should be ok: \n";
std::vector<int> v(100, 1);
test(v);
std::cout << "This will exceed buffer capacity: \n";
std::iota(v.begin(), v.end(), 42);
test(v);
}
打印
Should be ok:
Success: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
This will exceed buffer capacity:
Generation failed (insufficient capacity?)
我了解如何使用业力生成管理内存的容器,例如 std::string。但是如果缓冲区 (char[N]) 已经被预分配了呢?
{
using namespace boost::spirit::karma;
{
std::string buffer;
generate(std::inserter(buffer, buffer.begin()), double_, 3.13);
std::cout << ':' << buffer << ':' << std::endl;
}
{
//////////////////////////////////////////////////////////////////////
// How to make the following work? Is there a builtin output
// iterator that just works?
#if defined(MAJIC)
char buffer[1024];
generate(buffer, double_, 3.13);
std::cout << ':' << buffer << ':' << std::endl;
#endif
}
}
我想找到一种方法将双精度解析为现有缓冲区的地址。可以假设缓冲区对于这种情况足够大。也许潜在的问题真的是——是否已经有一个输出迭代器适配器或 karma 中可以使用的原生数组?
基于 Karma 迭代器的 API (here) 采用...输出迭代器。
你可以只为你的数组创建一个。
问题在于您需要非常确定缓冲区容量永远不会不足:
char buffer[1024];
char* it = buffer;
karma::generate(it, karma::double_ << karma::eol, 3.13);
std::cout.write(buffer, std::distance(buffer, it));
请注意,您不能假定缓冲区以 NUL 结尾。使用生成的大小。
安全使用 array_sink
:
Boost Iostreams 中有一种更方便、更通用的方法,它在面对固定大小的缓冲区时也是安全的:
char buffer[310];
io::stream<io::array_sink> as(buffer);
boost::spirit::ostream_iterator it(as);
这里有一个演示特性的现场演示:
#include <boost/spirit/include/karma.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
namespace karma = boost::spirit::karma;
namespace io = boost::iostreams;
void test(std::vector<int> const& v)
{
char buffer[310];
io::stream<io::array_sink> as(buffer);
boost::spirit::ostream_iterator it(as);
using namespace karma;
if (generate(it, int_ % ", " << eol, v))
{
std::cout << "Success: ";
std::cout.write(buffer, as.tellp());
} else
std::cout << "Generation failed (insufficient capacity?)\n";
}
int main() {
std::cout << "Should be ok: \n";
std::vector<int> v(100, 1);
test(v);
std::cout << "This will exceed buffer capacity: \n";
std::iota(v.begin(), v.end(), 42);
test(v);
}
打印
Should be ok:
Success: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
This will exceed buffer capacity:
Generation failed (insufficient capacity?)