Skip to content

Commit

Permalink
Rework basic_json element access to accept more key types
Browse files Browse the repository at this point in the history
Rework basic_json element access member functions and operators to
accept any type that meets the requirements defined by type trait
detail::is_usable_as_key_type.

Member functions and operators:
* at()
* operator[]
* value()
* erase()
* find()
* count()
* contains()

Update documentation to reflect these changes.

Add unit tests to excercise the new functions using std::string_view.

Co-authored-by: Niels Lohmann <niels.lohmann@gmail.com>
  • Loading branch information
falbrechtskirchinger and nlohmann committed Apr 13, 2022
1 parent 1e97a7e commit 1632077
Show file tree
Hide file tree
Showing 12 changed files with 976 additions and 171 deletions.
15 changes: 12 additions & 3 deletions doc/mkdocs/docs/api/basic_json/at.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ reference at(size_type idx);
const_reference at(size_type idx) const;

// (2)
reference at(const typename object_t::key_type& key);
const_reference at(const typename object_t::key_type& key) const;
template<typename KeyType>
reference at(const KeyType& key);
template<typename KeyType>
const_reference at(const KeyType& key) const;

// (3)
reference at(const json_pointer& ptr);
Expand All @@ -18,6 +20,13 @@ const_reference at(const json_pointer& ptr) const;
2. Returns a reference to the object element at with specified key `key`, with bounds checking.
3. Returns a reference to the element at with specified JSON pointer `ptr`, with bounds checking.
## Template parameters
`KeyType`
: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with [`string_t`](string_t.md)
using [`object_comparator_t`](object_comparator_t.md).
This can also be a string literal or a string view (C++17).
## Parameters
`idx` (in)
Expand Down Expand Up @@ -172,5 +181,5 @@ Strong exception safety: if an exception occurs, the original value stays intact
## Version history

1. Added in version 1.0.0.
2. Added in version 1.0.0.
2. Added in version 1.0.0. Added `KeyType` template in version 3.11.0.
3. Added in version 2.0.0.
12 changes: 7 additions & 5 deletions doc/mkdocs/docs/api/basic_json/contains.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

```cpp
// (1)
template<typename KeyT>
bool contains(KeyT && key) const;
template<typename KeyType>
bool contains(const KeyType& key) const;

// (2)
bool contains(const json_pointer& ptr) const;
Expand All @@ -15,8 +15,10 @@ bool contains(const json_pointer& ptr) const;
## Template parameters
`KeyT`
: A type for an object key other than `basic_json::json_pointer`.
`KeyType`
: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with [`string_t`](string_t.md)
using [`object_comparator_t`](object_comparator_t.md).
This can also be a string literal or a string view (C++17).
## Parameters
Expand Down Expand Up @@ -90,5 +92,5 @@ Logarithmic in the size of the JSON object.

## Version history

1. Added in version 3.6.0.
1. Added in version 3.6.0. Extended template `KeyType` to support any comparable type in version 3.11.0.
2. Added in version 3.7.0.
11 changes: 7 additions & 4 deletions doc/mkdocs/docs/api/basic_json/count.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# <small>nlohmann::basic_json::</small>count

```cpp
template<typename KeyT>
size_type count(KeyT&& key) const;
template<typename KeyType>
size_type count(const KeyType& key) const;
```
Returns the number of elements with key `key`. If `ObjectType` is the default `std::map` type, the return value will
always be `0` (`key` was not found) or `1` (`key` was found).
## Template parameters
`KeyT`
: A type for an object key.
`KeyType`
: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with [`string_t`](string_t.md)
using [`object_comparator_t`](object_comparator_t.md).
This can also be a string literal or a string view (C++17).
## Parameters
Expand Down Expand Up @@ -53,3 +55,4 @@ This method always returns `0` when executed on a JSON type that is not an objec
## Version history

- Added in version 1.0.0.
- Extended template `KeyType` to support any comparable type in version 3.11.0.
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ The actual comparator used depends on [`object_t`](object_t.md) and can be obtai

## Version history

- Added in version 3.10.6.
- Added in version 3.11.0.
11 changes: 10 additions & 1 deletion doc/mkdocs/docs/api/basic_json/erase.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ iterator erase(iterator first, iterator last);
const_iterator erase(const_iterator first, const_iterator last);

// (3)
size_type erase(const typename object_t::key_type& key);
template<typename KeyType>
size_type erase(const KeyType& key);

// (4)
void erase(const size_type idx);
Expand All @@ -31,6 +32,13 @@ void erase(const size_type idx);
4. Removes an element from a JSON array by index.
## Template parameters
`KeyType`
: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with [`string_t`](string_t.md)
using [`object_comparator_t`](object_comparator_t.md).
This can also be a string literal or a string view (C++17).
## Parameters
`pos` (in)
Expand Down Expand Up @@ -174,3 +182,4 @@ Strong exception safety: if an exception occurs, the original value stays intact

- Added in version 1.0.0.
- Added support for binary types in version 3.8.0.
- Added `KeyType` template in version 3.11.0.
15 changes: 9 additions & 6 deletions doc/mkdocs/docs/api/basic_json/find.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
# <small>nlohmann::basic_json::</small>find

```cpp
template<typename KeyT>
iterator find(KeyT&& key);
template<typename KeyType>
iterator find(const KeyType& key);

template<typename KeyT>
const_iterator find(KeyT&& key) const;
template<typename KeyType>
const_iterator find(const KeyType& key) const;
```
Finds an element in a JSON object with key equivalent to `key`. If the element is not found or the JSON value is not an
object, `end()` is returned.
## Template parameters
`KeyT`
: A type for an object key.
`KeyType`
: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with [`string_t`](string_t.md)
using [`object_comparator_t`](object_comparator_t.md).
This can also be a string literal or a string view (C++17).
## Parameters
Expand Down Expand Up @@ -61,3 +63,4 @@ This method always returns `end()` when executed on a JSON type that is not an o
## Version history

- Added in version 1.0.0.
- Extended template `KeyType` to support any comparable type and changed from rvalue reference to const lvalue reference in version 3.11.0.
23 changes: 12 additions & 11 deletions doc/mkdocs/docs/api/basic_json/operator[].md
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ reference operator[](size_type idx);
const_reference operator[](size_type idx) const;

// (2)
reference operator[](const typename object_t::key_type& key);
const_reference operator[](const typename object_t::key_type& key) const;
template<typename T>
reference operator[](T* key);
template<typename T>
const_reference operator[](T* key) const;
template<typename KeyType>
reference operator[](KeyType && key);
template<typename KeyType>
const_reference operator[](KeyType && key) const;

// (3)
reference operator[](const json_pointer& ptr);
const_reference operator[](const json_pointer& ptr) const;
```

1. Returns a reference to the array element at specified location `idx`.
2. Returns a reference to the object element at with specified key `key`.
3. Returns a reference to the element at with specified JSON pointer `ptr`.
2. Returns a reference to the object element with specified key `key`.
3. Returns a reference to the element with specified JSON pointer `ptr`.

## Template parameters

`T`
: string literal convertible to `object_t::key_type`
`KeyType`
: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with [`string_t`](string_t.md)
using [`object_comparator_t`](object_comparator_t.md).
This can also be a string literal or a string view (C++17).

## Parameters

Expand Down Expand Up @@ -192,5 +192,6 @@ Strong exception safety: if an exception occurs, the original value stays intact
## Version history

1. Added in version 1.0.0.
2. Added in version 1.0.0. Overloads for `T* key` added in version 1.1.0.
2. Added in version 1.0.0. Overloads for `T* key` added in version 1.1.0. Template `T* key` replaced by template `KeyType`
in version 3.11.0 which now also supports `std::string_view`.
3. Added in version 2.0.0.
12 changes: 8 additions & 4 deletions doc/mkdocs/docs/api/basic_json/value.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

```cpp
// (1)
template<class ValueType>
ValueType value(const typename object_t::key_type& key,
const ValueType& default_value) const;
template<class KeyType, class ValueType>
ValueType value(const KeyType& key,
ValueType && default_value) const;

// (2)
template<class ValueType>
Expand Down Expand Up @@ -44,6 +44,10 @@ ValueType value(const json_pointer& ptr,

## Template parameters

`KeyType`
: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with [`string_t`](string_t.md)
using [`object_comparator_t`](object_comparator_t.md).
This can also be a string literal or a string view (C++17).
`ValueType`
: type compatible to JSON values, for instance `#!cpp int` for JSON integer numbers, `#!cpp bool` for JSON booleans,
or `#!cpp std::vector` types for JSON arrays. Note the type of the expected value at `key`/`ptr` and the default
Expand Down Expand Up @@ -125,5 +129,5 @@ changes to any JSON value.

## Version history

1. Added in version 1.0.0.
1. Added in version 1.0.0. Added `KeyType` template parameter in 3.11.0.
2. Added in version 2.0.2.
11 changes: 11 additions & 0 deletions include/nlohmann/detail/meta/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,17 @@ using has_erase_with_key_type = typename std::conditional <
std::true_type,
std::false_type >::type;


template<typename ObjectType, typename KeyType>
using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<const KeyType&>()));

// type trait to check if object_t has an erase() member functions accepting const KeyType&
template<typename BasicJsonType, typename KeyType, typename UnqualKeyType = uncvref_t<KeyType>>
struct has_erase_with_key_type : std::conditional <
is_detected<detect_erase_with_key_type, typename BasicJsonType::object_t, UnqualKeyType>::value,
std::true_type,
std::false_type >::type {};

// a naive helper to check if a type is an ordered_map (exploits the fact that
// ordered_map inherits capacity() from std::vector)
template <typename T>
Expand Down
Loading

0 comments on commit 1632077

Please sign in to comment.