fix: put comment just after non-table values

When non-table value is passed to the `operator<<`, it assumes that the
original C++ code looks like the following.

```cpp
std::cout << "key = " << v << std::endl;
```

In this case, the comment associated to `v` should be put just after
`v`, not before.
```toml
key = # comment <= bad
"value"

key = "value" # comment <= good
```

So, if `v` is not a table it would put comments just after the value.
This commit is contained in:
ToruNiina 2019-06-28 17:53:19 +09:00
parent 37e96ed8dc
commit 3624e4b690

View File

@ -682,13 +682,36 @@ operator<<(std::basic_ostream<charT, traits>& os, const basic_value<C, M, V>& v)
const int fprec = static_cast<int>(os.precision()); const int fprec = static_cast<int>(os.precision());
os.width(0); os.width(0);
if(!v.comments().empty()) if(v.is_table() && !v.comments().empty())
{ {
os << v.comments(); os << v.comments();
os << '\n'; // to split the file comment from the first element os << '\n'; // to split the file comment from the first element
} }
// the root object can't be an inline table. so pass `false`. // the root object can't be an inline table. so pass `false`.
os << visit(serializer<C, M, V>(w, fprec, false), v); os << visit(serializer<C, M, V>(w, fprec, false), v);
// if v is a non-table value, and has only one comment, then
// put a comment just after a value. in the following way.
//
// ```toml
// key = "value" # comment.
// ```
//
// Since the top-level toml object is a table, one who want to put a
// non-table toml value must use this in a following way.
//
// ```cpp
// toml::value v;
// std::cout << "user-defined-key = " << v << std::endl;
// ```
//
// In this case, it is impossible to put comments before key-value pair.
// The only way to preserve comments is to put all of them after a value.
if(!v.is_table() && !v.comments().empty())
{
os << " #";
for(const auto& c : v.comments()) {os << c;}
}
return os; return os;
} }