Skip to content

Commit

Permalink
Merge pull request nlohmann#22 from nlohmann/develop
Browse files Browse the repository at this point in the history
Sync Fork from Upstream Repo
  • Loading branch information
sthagen authored Aug 2, 2020
2 parents 01f0bfa + f4155e4 commit 9687200
Show file tree
Hide file tree
Showing 10 changed files with 1,006 additions and 420 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1611,7 +1611,7 @@ Here is a related issue [#1924](https://github.com/nlohmann/json/issues/1924).
- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](https://en.cppreference.com/w/cpp/error/assert). In particular, note [`operator[]`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a233b02b0839ef798942dd46157cc0fe6.html#a233b02b0839ef798942dd46157cc0fe6) implements **unchecked access** for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an [assertion failure](https://github.com/nlohmann/json/issues/289) if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the [`at()` function](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a73ae333487310e3302135189ce8ff5d8.html#a73ae333487310e3302135189ce8ff5d8). Furthermore, you can define `JSON_ASSERT(x)` to replace calls to `assert(x)`.
- As the exact type of a number is not defined in the [JSON specification](https://tools.ietf.org/html/rfc8259.html), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions.
- The code can be compiled without C++ **runtime type identification** features; that is, you can use the `-fno-rtti` compiler flag.
- **Exceptions** are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER´` (overriding `throw`), `JSON_TRY_USER` (overriding `try`), and `JSON_CATCH_USER` (overriding `catch`). Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
- **Exceptions** are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `throw`), `JSON_TRY_USER` (overriding `try`), and `JSON_CATCH_USER` (overriding `catch`). Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
## Execute unit tests
Expand Down
12 changes: 6 additions & 6 deletions doc/mkdocs/docs/integration/package_managers.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ If you are using OS X and [Homebrew](http://brew.sh), just type

```sh
brew tap nlohmann/json
brew install nlohmann_json
brew install nlohmann-json
```

and you're set. If you want the bleeding edge rather than the latest release, use

```sh
brew tap nlohmann/json
brew install nlohmann_json --HEAD
brew install nlohmann-json --HEAD
```

instead.
Expand All @@ -38,19 +38,19 @@ instead.

```sh
brew tap nlohmann/json
brew install nlohmann_json
brew install nlohmann-json
```

3. Determine the include path, which defaults to `/usr/local/Cellar/nlohmann_json/$version/include`, where `$version` is the version of the library, e.g. `3.7.3`. The path of the library can be determined with
3. Determine the include path, which defaults to `/usr/local/Cellar/nlohmann-json/$version/include`, where `$version` is the version of the library, e.g. `3.7.3`. The path of the library can be determined with

```sh
brew list nlohmann_json
brew list nlohmann-json
```

4. Compile the code. For instance, the code can be compiled using Clang with

```sh
clang++ example.cpp -I/usr/local/Cellar/nlohmann_json/3.7.3/include -std=c++11 -o example
clang++ example.cpp -I/usr/local/Cellar/nlohmann-json/3.7.3/include -std=c++11 -o example
```

## Meson
Expand Down
6 changes: 3 additions & 3 deletions include/nlohmann/detail/input/lexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,13 +880,13 @@ class lexer : public lexer_base<BasicJsonType>
default:
{
unget();
break;
continue;
}
}
}

default:
break;
continue;
}
}
}
Expand Down Expand Up @@ -1511,7 +1511,7 @@ class lexer : public lexer_base<BasicJsonType>
skip_whitespace();

// ignore comments
if (ignore_comments && current == '/')
while (ignore_comments && current == '/')
{
if (!scan_comment())
{
Expand Down
106 changes: 103 additions & 3 deletions include/nlohmann/ordered_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
using mapped_type = T;
using Container = std::vector<std::pair<const Key, T>, Allocator>;
using typename Container::iterator;
using typename Container::const_iterator;
using typename Container::size_type;
using typename Container::value_type;

Expand All @@ -30,7 +31,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
: Container{init, alloc} {}

std::pair<iterator, bool> emplace(key_type&& key, T&& t)
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
Expand All @@ -43,9 +44,40 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return {--this->end(), true};
}

T& operator[](Key&& key)
T& operator[](const Key& key)
{
return emplace(std::move(key), T{}).first->second;
return emplace(key, T{}).first->second;
}

const T& operator[](const Key& key) const
{
return at(key);
}

T& at(const Key& key)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == key)
{
return it->second;
}
}

throw std::out_of_range("key not found");
}

const T& at(const Key& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == key)
{
return it->second;
}
}

throw std::out_of_range("key not found");
}

size_type erase(const Key& key)
Expand All @@ -66,6 +98,74 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
}
return 0;
}

iterator erase(iterator pos)
{
auto it = pos;

// Since we cannot move const Keys, re-construct them in place
for (auto next = it; ++next != this->end(); ++it)
{
it->~value_type(); // Destroy but keep allocation
new (&*it) value_type{std::move(*next)};
}
Container::pop_back();
return pos;
}

size_type count(const Key& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == key)
{
return 1;
}
}
return 0;
}

iterator find(const Key& key)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == key)
{
return it;
}
}
return Container::end();
}

const_iterator find(const Key& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == key)
{
return it;
}
}
return Container::end();
}

std::pair<iterator, bool> insert( value_type&& value )
{
return emplace(value.first, std::move(value.second));
}

std::pair<iterator, bool> insert( const value_type& value )
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == value.first)
{
return {it, false};
}
}
Container::push_back(value);
return {--this->end(), true};
}
};

} // namespace nlohmann
112 changes: 106 additions & 6 deletions single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6759,13 +6759,13 @@ class lexer : public lexer_base<BasicJsonType>
default:
{
unget();
break;
continue;
}
}
}

default:
break;
continue;
}
}
}
Expand Down Expand Up @@ -7390,7 +7390,7 @@ class lexer : public lexer_base<BasicJsonType>
skip_whitespace();

// ignore comments
if (ignore_comments && current == '/')
while (ignore_comments && current == '/')
{
if (!scan_comment())
{
Expand Down Expand Up @@ -16408,6 +16408,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
using mapped_type = T;
using Container = std::vector<std::pair<const Key, T>, Allocator>;
using typename Container::iterator;
using typename Container::const_iterator;
using typename Container::size_type;
using typename Container::value_type;

Expand All @@ -16420,7 +16421,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
: Container{init, alloc} {}

std::pair<iterator, bool> emplace(key_type&& key, T&& t)
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
Expand All @@ -16433,9 +16434,40 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return {--this->end(), true};
}

T& operator[](Key&& key)
T& operator[](const Key& key)
{
return emplace(key, T{}).first->second;
}

const T& operator[](const Key& key) const
{
return at(key);
}

T& at(const Key& key)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == key)
{
return it->second;
}
}

throw std::out_of_range("key not found");
}

const T& at(const Key& key) const
{
return emplace(std::move(key), T{}).first->second;
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == key)
{
return it->second;
}
}

throw std::out_of_range("key not found");
}

size_type erase(const Key& key)
Expand All @@ -16456,6 +16488,74 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
}
return 0;
}

iterator erase(iterator pos)
{
auto it = pos;

// Since we cannot move const Keys, re-construct them in place
for (auto next = it; ++next != this->end(); ++it)
{
it->~value_type(); // Destroy but keep allocation
new (&*it) value_type{std::move(*next)};
}
Container::pop_back();
return pos;
}

size_type count(const Key& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == key)
{
return 1;
}
}
return 0;
}

iterator find(const Key& key)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == key)
{
return it;
}
}
return Container::end();
}

const_iterator find(const Key& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == key)
{
return it;
}
}
return Container::end();
}

std::pair<iterator, bool> insert( value_type&& value )
{
return emplace(value.first, std::move(value.second));
}

std::pair<iterator, bool> insert( const value_type& value )
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (it->first == value.first)
{
return {it, false};
}
}
Container::push_back(value);
return {--this->end(), true};
}
};

} // namespace nlohmann
Expand Down
4 changes: 3 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,12 @@ set(files
src/unit-msgpack.cpp
src/unit-noexcept.cpp
src/unit-ordered_json.cpp
src/unit-ordered_map.cpp
src/unit-pointer_access.cpp
src/unit-readme.cpp
src/unit-reference_access.cpp
src/unit-regression.cpp
src/unit-regression1.cpp
src/unit-regression2.cpp
src/unit-serialization.cpp
src/unit-testsuites.cpp
src/unit-to_chars.cpp
Expand Down
3 changes: 3 additions & 0 deletions test/src/unit-class_lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,5 +241,8 @@ TEST_CASE("lexer class")
CHECK((scan_string("/* true */", true) == json::lexer::token_type::end_of_input));
CHECK((scan_string("/*/**/", true) == json::lexer::token_type::end_of_input));
CHECK((scan_string("/*/* */", true) == json::lexer::token_type::end_of_input));

CHECK((scan_string("//\n//\n", true) == json::lexer::token_type::end_of_input));
CHECK((scan_string("/**//**//**/", true) == json::lexer::token_type::end_of_input));
}
}
Loading

0 comments on commit 9687200

Please sign in to comment.