Upgrade to C++20 (#4239)

* Use explicit this capture required by C++20
* Use C++20 span
* Replace wpi::numbers with std::numbers
* Fix C++20 clang-tidy warning false positive in fmt
* Remove ciso646 include since C++20 removed that header
* Fix global-buffer-overflow asan warnings in ntcore tests
* Add DIOSetProxy constructor to HAL

* Upgrade MSVC compiler to 2022
* Bump native-utils to 2023.2.7 (changes to std=c++20)

Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
This commit is contained in:
Tyler Veness
2022-10-15 16:33:14 -07:00
committed by GitHub
parent 396143004c
commit fbdc810887
355 changed files with 1659 additions and 2918 deletions

View File

@@ -5,11 +5,11 @@
#pragma once
#include <initializer_list>
#include <span>
#include <hal/AddressableLEDTypes.h>
#include <hal/Types.h>
#include <units/time.h>
#include <wpi/span.h>
#include "util/Color.h"
#include "util/Color8Bit.h"
@@ -107,7 +107,7 @@ class AddressableLED {
*
* @param ledData the buffer to write
*/
void SetData(wpi::span<const LEDData> ledData);
void SetData(std::span<const LEDData> ledData);
/**
* Sets the led output data.

View File

@@ -7,11 +7,11 @@
#include <stdint.h>
#include <memory>
#include <span>
#include <hal/SPITypes.h>
#include <units/time.h>
#include <wpi/deprecated.h>
#include <wpi/span.h>
namespace frc {
@@ -196,7 +196,7 @@ class SPI {
* @param dataToSend data to send (maximum 16 bytes)
* @param zeroSize number of zeros to send after the data
*/
void SetAutoTransmitData(wpi::span<const uint8_t> dataToSend, int zeroSize);
void SetAutoTransmitData(std::span<const uint8_t> dataToSend, int zeroSize);
/**
* Start running the automatic SPI transfer engine at a periodic rate.

View File

@@ -5,10 +5,9 @@
#pragma once
#include <memory>
#include <span>
#include <string>
#include <wpi/span.h>
#include "frc/MotorSafety.h"
namespace frc {
@@ -75,7 +74,7 @@ class RobotDriveBase : public MotorSafety {
* Renormalize all wheel speeds if the magnitude of any wheel is greater than
* 1.0.
*/
static void Desaturate(wpi::span<double> wheelSpeeds);
static void Desaturate(std::span<double> wheelSpeeds);
double m_deadband = 0.02;
double m_maxOutput = 1.0;

View File

@@ -6,6 +6,7 @@
#include <functional>
#include <memory>
#include <span>
#include <string>
#include <string_view>
@@ -25,7 +26,6 @@ using CS_Source = CS_Handle; // NOLINT
#include <networktables/StringArrayTopic.h>
#include <wpi/sendable/Sendable.h>
#include <wpi/sendable/SendableHelper.h>
#include <wpi/span.h>
namespace frc {
@@ -64,7 +64,7 @@ class SendableCameraWrapper
* @param cameraUrls camera URLs
*/
SendableCameraWrapper(std::string_view cameraName,
wpi::span<const std::string> cameraUrls,
std::span<const std::string> cameraUrls,
const private_init&);
/**
@@ -79,7 +79,7 @@ class SendableCameraWrapper
static SendableCameraWrapper& Wrap(CS_Source source);
static SendableCameraWrapper& Wrap(std::string_view cameraName,
wpi::span<const std::string> cameraUrls);
std::span<const std::string> cameraUrls);
void InitSendable(wpi::SendableBuilder& builder) override;
@@ -97,7 +97,7 @@ inline SendableCameraWrapper::SendableCameraWrapper(std::string_view name,
}
inline SendableCameraWrapper::SendableCameraWrapper(
std::string_view cameraName, wpi::span<const std::string> cameraUrls,
std::string_view cameraName, std::span<const std::string> cameraUrls,
const private_init&)
: SendableCameraWrapper(cameraName, private_init{}) {
m_streams = nt::NetworkTableInstance::GetDefault()
@@ -123,7 +123,7 @@ inline SendableCameraWrapper& SendableCameraWrapper::Wrap(CS_Source source) {
}
inline SendableCameraWrapper& SendableCameraWrapper::Wrap(
std::string_view cameraName, wpi::span<const std::string> cameraUrls) {
std::string_view cameraName, std::span<const std::string> cameraUrls) {
auto& wrapper = detail::GetSendableCameraWrapper(cameraName);
if (!wrapper) {
wrapper = std::make_shared<SendableCameraWrapper>(cameraName, cameraUrls,

View File

@@ -6,6 +6,7 @@
#include <functional>
#include <memory>
#include <span>
#include <string>
#include <string_view>
#include <vector>
@@ -14,7 +15,6 @@
#include <networktables/NetworkTableValue.h>
#include <wpi/SmallSet.h>
#include <wpi/StringMap.h>
#include <wpi/span.h>
#include "frc/shuffleboard/BuiltInLayouts.h"
#include "frc/shuffleboard/LayoutType.h"
@@ -137,7 +137,7 @@ class ShuffleboardContainer : public virtual ShuffleboardValue {
* @return a widget to display the camera stream
*/
ComplexWidget& AddCamera(std::string_view title, std::string_view cameraName,
wpi::span<const std::string> cameraUrls);
std::span<const std::string> cameraUrls);
/**
* Adds a widget to this container to display the given sendable.
@@ -259,10 +259,10 @@ class ShuffleboardContainer : public virtual ShuffleboardValue {
* @return a widget to display the sendable data
* @throws IllegalArgumentException if a widget already exists in this
* container with the given title
* @see AddPersistent(std::string_view, wpi::span<const bool>)
* Add(std::string_view title, wpi::span<const bool> defaultValue)
* @see AddPersistent(std::string_view, std::span<const bool>)
* Add(std::string_view title, std::span<const bool> defaultValue)
*/
SimpleWidget& Add(std::string_view title, wpi::span<const bool> defaultValue);
SimpleWidget& Add(std::string_view title, std::span<const bool> defaultValue);
/**
* Adds a widget to this container to display the given data.
@@ -272,11 +272,11 @@ class ShuffleboardContainer : public virtual ShuffleboardValue {
* @return a widget to display the sendable data
* @throws IllegalArgumentException if a widget already exists in this
* container with the given title
* @see AddPersistent(std::string_view, wpi::span<const double>)
* Add(std::string_view title, wpi::span<const double> defaultValue)
* @see AddPersistent(std::string_view, std::span<const double>)
* Add(std::string_view title, std::span<const double> defaultValue)
*/
SimpleWidget& Add(std::string_view title,
wpi::span<const double> defaultValue);
std::span<const double> defaultValue);
/**
* Adds a widget to this container to display the given data.
@@ -286,11 +286,11 @@ class ShuffleboardContainer : public virtual ShuffleboardValue {
* @return a widget to display the sendable data
* @throws IllegalArgumentException if a widget already exists in this
* container with the given title
* @see AddPersistent(std::string_view, wpi::span<const double>)
* Add(std::string_view title, wpi::span<const double> defaultValue)
* @see AddPersistent(std::string_view, std::span<const double>)
* Add(std::string_view title, std::span<const double> defaultValue)
*/
SimpleWidget& Add(std::string_view title,
wpi::span<const float> defaultValue);
std::span<const float> defaultValue);
/**
* Adds a widget to this container to display the given data.
@@ -300,11 +300,11 @@ class ShuffleboardContainer : public virtual ShuffleboardValue {
* @return a widget to display the sendable data
* @throws IllegalArgumentException if a widget already exists in this
* container with the given title
* @see AddPersistent(std::string_view, wpi::span<const double>)
* Add(std::string_view title, wpi::span<const double> defaultValue)
* @see AddPersistent(std::string_view, std::span<const double>)
* Add(std::string_view title, std::span<const double> defaultValue)
*/
SimpleWidget& Add(std::string_view title,
wpi::span<const int64_t> defaultValue);
std::span<const int64_t> defaultValue);
/**
* Adds a widget to this container to display the given data.
@@ -314,11 +314,11 @@ class ShuffleboardContainer : public virtual ShuffleboardValue {
* @return a widget to display the sendable data
* @throws IllegalArgumentException if a widget already exists in this
* container with the given title
* @see AddPersistent(std::string_view, wpi::span<const std::string>)
* Add(std::string_view title, wpi::span<const std::string> defaultValue)
* @see AddPersistent(std::string_view, std::span<const std::string>)
* Add(std::string_view title, std::span<const std::string> defaultValue)
*/
SimpleWidget& Add(std::string_view title,
wpi::span<const std::string> defaultValue);
std::span<const std::string> defaultValue);
/**
* Adds a widget to this container. The widget will display the data provided
@@ -600,82 +600,82 @@ class ShuffleboardContainer : public virtual ShuffleboardValue {
/**
* Adds a widget to this container to display a simple piece of data.
*
* Unlike Add(std::string_view, wpi::span<const bool>), the value in the
* Unlike Add(std::string_view, std::span<const bool>), the value in the
* widget will be saved on the robot and will be used when the robot program
* next starts rather than {@code defaultValue}.
*
* @param title the title of the widget
* @param defaultValue the default value of the widget
* @return a widget to display the sendable data
* @see Add(std::string_view, wpi::span<const bool>)
* Add(std::string_view title, wpi::span<const bool> defaultValue)
* @see Add(std::string_view, std::span<const bool>)
* Add(std::string_view title, std::span<const bool> defaultValue)
*/
SimpleWidget& AddPersistent(std::string_view title,
wpi::span<const bool> defaultValue);
std::span<const bool> defaultValue);
/**
* Adds a widget to this container to display a simple piece of data.
*
* Unlike Add(std::string_view, wpi::span<const double>), the value in the
* Unlike Add(std::string_view, std::span<const double>), the value in the
* widget will be saved on the robot and will be used when the robot program
* next starts rather than {@code defaultValue}.
*
* @param title the title of the widget
* @param defaultValue the default value of the widget
* @return a widget to display the sendable data
* @see Add(std::string_view, wpi::span<const double>)
* Add(std::string_view title, wpi::span<const double> defaultValue)
* @see Add(std::string_view, std::span<const double>)
* Add(std::string_view title, std::span<const double> defaultValue)
*/
SimpleWidget& AddPersistent(std::string_view title,
wpi::span<const double> defaultValue);
std::span<const double> defaultValue);
/**
* Adds a widget to this container to display a simple piece of data.
*
* Unlike Add(std::string_view, wpi::span<const float>), the value in the
* Unlike Add(std::string_view, std::span<const float>), the value in the
* widget will be saved on the robot and will be used when the robot program
* next starts rather than {@code defaultValue}.
*
* @param title the title of the widget
* @param defaultValue the default value of the widget
* @return a widget to display the sendable data
* @see Add(std::string_view, wpi::span<const float>)
* Add(std::string_view title, wpi::span<const float> defaultValue)
* @see Add(std::string_view, std::span<const float>)
* Add(std::string_view title, std::span<const float> defaultValue)
*/
SimpleWidget& AddPersistent(std::string_view title,
wpi::span<const float> defaultValue);
std::span<const float> defaultValue);
/**
* Adds a widget to this container to display a simple piece of data.
*
* Unlike Add(std::string_view, wpi::span<const int64_t>), the value in the
* Unlike Add(std::string_view, std::span<const int64_t>), the value in the
* widget will be saved on the robot and will be used when the robot program
* next starts rather than {@code defaultValue}.
*
* @param title the title of the widget
* @param defaultValue the default value of the widget
* @return a widget to display the sendable data
* @see Add(std::string_view, wpi::span<const int64_t>)
* Add(std::string_view title, wpi::span<const int64_t> defaultValue)
* @see Add(std::string_view, std::span<const int64_t>)
* Add(std::string_view title, std::span<const int64_t> defaultValue)
*/
SimpleWidget& AddPersistent(std::string_view title,
wpi::span<const int64_t> defaultValue);
std::span<const int64_t> defaultValue);
/**
* Adds a widget to this container to display a simple piece of data.
*
* Unlike Add(std::string_view, wpi::span<const std::string>), the value in
* Unlike Add(std::string_view, std::span<const std::string>), the value in
* the widget will be saved on the robot and will be used when the robot
* program next starts rather than {@code defaultValue}.
*
* @param title the title of the widget
* @param defaultValue the default value of the widget
* @return a widget to display the sendable data
* @see Add(std::string_view, wpi::span<const std::string>)
* Add(std::string_view title, wpi::span<const std::string> defaultValue)
* @see Add(std::string_view, std::span<const std::string>)
* Add(std::string_view title, std::span<const std::string> defaultValue)
*/
SimpleWidget& AddPersistent(std::string_view title,
wpi::span<const std::string> defaultValue);
std::span<const std::string> defaultValue);
void EnableIfActuator() override;
@@ -721,7 +721,7 @@ inline frc::ComplexWidget& frc::ShuffleboardContainer::Add(
inline frc::ComplexWidget& frc::ShuffleboardContainer::AddCamera(
std::string_view title, std::string_view cameraName,
wpi::span<const std::string> cameraUrls) {
std::span<const std::string> cameraUrls) {
return Add(title, frc::SendableCameraWrapper::Wrap(cameraName, cameraUrls));
}
#endif

View File

@@ -5,11 +5,11 @@
#pragma once
#include <numeric>
#include <span>
#include <units/current.h>
#include <units/impedance.h>
#include <units/voltage.h>
#include <wpi/span.h>
namespace frc::sim {
@@ -32,7 +32,7 @@ class BatterySim {
*/
static units::volt_t Calculate(units::volt_t nominalVoltage,
units::ohm_t resistance,
wpi::span<const units::ampere_t> currents) {
std::span<const units::ampere_t> currents) {
return nominalVoltage -
std::accumulate(currents.begin(), currents.end(), 0_A) * resistance;
}
@@ -66,7 +66,7 @@ class BatterySim {
* @param currents The currents drawn from the battery.
* @return The battery's voltage under load.
*/
static units::volt_t Calculate(wpi::span<const units::ampere_t> currents) {
static units::volt_t Calculate(std::span<const units::ampere_t> currents) {
return Calculate(12_V, 0.02_Ohm, currents);
}

View File

@@ -5,6 +5,7 @@
#pragma once
#include <initializer_list>
#include <span>
#include <string>
#include <string_view>
#include <utility>
@@ -14,7 +15,6 @@
#include <units/length.h>
#include <wpi/SmallVector.h>
#include <wpi/mutex.h>
#include <wpi/span.h>
#include "frc/geometry/Pose2d.h"
#include "frc/geometry/Rotation2d.h"
@@ -66,7 +66,7 @@ class FieldObject2d {
*
* @param poses array of 2D poses
*/
void SetPoses(wpi::span<const Pose2d> poses);
void SetPoses(std::span<const Pose2d> poses);
/**
* Set multiple poses from an array of Pose objects.
@@ -97,7 +97,7 @@ class FieldObject2d {
* @param out output SmallVector to hold 2D poses
* @return span referring to output SmallVector
*/
wpi::span<const Pose2d> GetPoses(wpi::SmallVectorImpl<Pose2d>& out) const;
std::span<const Pose2d> GetPoses(wpi::SmallVectorImpl<Pose2d>& out) const;
private:
void UpdateEntry(bool setDefault = false);

View File

@@ -6,6 +6,7 @@
#include <functional>
#include <memory>
#include <span>
#include <string>
#include <string_view>
#include <utility>
@@ -17,7 +18,6 @@
#include <networktables/StringTopic.h>
#include <wpi/FunctionExtras.h>
#include <wpi/SmallVector.h>
#include <wpi/span.h>
namespace frc {
@@ -111,28 +111,28 @@ class SendableBuilderImpl : public nt::NTSendableBuilder {
void AddBooleanArrayProperty(
std::string_view key, std::function<std::vector<int>()> getter,
std::function<void(wpi::span<const int>)> setter) override;
std::function<void(std::span<const int>)> setter) override;
void AddIntegerArrayProperty(
std::string_view key, std::function<std::vector<int64_t>()> getter,
std::function<void(wpi::span<const int64_t>)> setter) override;
std::function<void(std::span<const int64_t>)> setter) override;
void AddFloatArrayProperty(
std::string_view key, std::function<std::vector<float>()> getter,
std::function<void(wpi::span<const float>)> setter) override;
std::function<void(std::span<const float>)> setter) override;
void AddDoubleArrayProperty(
std::string_view key, std::function<std::vector<double>()> getter,
std::function<void(wpi::span<const double>)> setter) override;
std::function<void(std::span<const double>)> setter) override;
void AddStringArrayProperty(
std::string_view key, std::function<std::vector<std::string>()> getter,
std::function<void(wpi::span<const std::string>)> setter) override;
std::function<void(std::span<const std::string>)> setter) override;
void AddRawProperty(
std::string_view key, std::string_view typeString,
std::function<std::vector<uint8_t>()> getter,
std::function<void(wpi::span<const uint8_t>)> setter) override;
std::function<void(std::span<const uint8_t>)> setter) override;
void AddSmallStringProperty(
std::string_view key,
@@ -141,41 +141,41 @@ class SendableBuilderImpl : public nt::NTSendableBuilder {
void AddSmallBooleanArrayProperty(
std::string_view key,
std::function<wpi::span<const int>(wpi::SmallVectorImpl<int>& buf)>
std::function<std::span<const int>(wpi::SmallVectorImpl<int>& buf)>
getter,
std::function<void(wpi::span<const int>)> setter) override;
std::function<void(std::span<const int>)> setter) override;
void AddSmallIntegerArrayProperty(
std::string_view key,
std::function<
wpi::span<const int64_t>(wpi::SmallVectorImpl<int64_t>& buf)>
std::span<const int64_t>(wpi::SmallVectorImpl<int64_t>& buf)>
getter,
std::function<void(wpi::span<const int64_t>)> setter) override;
std::function<void(std::span<const int64_t>)> setter) override;
void AddSmallFloatArrayProperty(
std::string_view key,
std::function<wpi::span<const float>(wpi::SmallVectorImpl<float>& buf)>
std::function<std::span<const float>(wpi::SmallVectorImpl<float>& buf)>
getter,
std::function<void(wpi::span<const float>)> setter) override;
std::function<void(std::span<const float>)> setter) override;
void AddSmallDoubleArrayProperty(
std::string_view key,
std::function<wpi::span<const double>(wpi::SmallVectorImpl<double>& buf)>
std::function<std::span<const double>(wpi::SmallVectorImpl<double>& buf)>
getter,
std::function<void(wpi::span<const double>)> setter) override;
std::function<void(std::span<const double>)> setter) override;
void AddSmallStringArrayProperty(
std::string_view key,
std::function<
wpi::span<const std::string>(wpi::SmallVectorImpl<std::string>& buf)>
std::span<const std::string>(wpi::SmallVectorImpl<std::string>& buf)>
getter,
std::function<void(wpi::span<const std::string>)> setter) override;
std::function<void(std::span<const std::string>)> setter) override;
void AddSmallRawProperty(
std::string_view key, std::string_view typeString,
std::function<wpi::span<uint8_t>(wpi::SmallVectorImpl<uint8_t>& buf)>
std::function<std::span<uint8_t>(wpi::SmallVectorImpl<uint8_t>& buf)>
getter,
std::function<void(wpi::span<const uint8_t>)> setter) override;
std::function<void(std::span<const uint8_t>)> setter) override;
private:
struct Property {

View File

@@ -58,7 +58,7 @@ void SendableChooser<T>::InitSendable(nt::NTSendableBuilder& builder) {
}
builder.AddStringArrayProperty(
kOptions,
[=] {
[=, this] {
std::vector<std::string> keys;
for (const auto& choice : m_choices) {
keys.emplace_back(choice.first());
@@ -73,13 +73,13 @@ void SendableChooser<T>::InitSendable(nt::NTSendableBuilder& builder) {
nullptr);
builder.AddSmallStringProperty(
kDefault,
[=](wpi::SmallVectorImpl<char>&) -> std::string_view {
[=, this](wpi::SmallVectorImpl<char>&) -> std::string_view {
return m_defaultChoice;
},
nullptr);
builder.AddSmallStringProperty(
kActive,
[=](wpi::SmallVectorImpl<char>& buf) -> std::string_view {
[=, this](wpi::SmallVectorImpl<char>& buf) -> std::string_view {
std::scoped_lock lock(m_mutex);
if (m_haveSelected) {
buf.assign(m_selected.begin(), m_selected.end());
@@ -89,14 +89,15 @@ void SendableChooser<T>::InitSendable(nt::NTSendableBuilder& builder) {
}
},
nullptr);
builder.AddStringProperty(kSelected, nullptr, [=](std::string_view val) {
std::scoped_lock lock(m_mutex);
m_haveSelected = true;
m_selected = val;
for (auto& pub : m_activePubs) {
pub.Set(val);
}
});
builder.AddStringProperty(kSelected, nullptr,
[=, this](std::string_view val) {
std::scoped_lock lock(m_mutex);
m_haveSelected = true;
m_selected = val;
for (auto& pub : m_activePubs) {
pub.Set(val);
}
});
}
template <class T>

View File

@@ -5,13 +5,13 @@
#pragma once
#include <memory>
#include <span>
#include <string>
#include <string_view>
#include <vector>
#include <networktables/NetworkTableEntry.h>
#include <networktables/NetworkTableValue.h>
#include <wpi/span.h>
namespace wpi {
class Sendable;
@@ -216,7 +216,7 @@ class SmartDashboard {
* std::vector<bool> is special-cased in C++. 0 is false, any
* non-zero value is true.
*/
static bool PutBooleanArray(std::string_view key, wpi::span<const int> value);
static bool PutBooleanArray(std::string_view key, std::span<const int> value);
/**
* Gets the current value in the table, setting it if it does not exist.
@@ -226,7 +226,7 @@ class SmartDashboard {
* @returns False if the table key exists with a different type
*/
static bool SetDefaultBooleanArray(std::string_view key,
wpi::span<const int> defaultValue);
std::span<const int> defaultValue);
/**
* Returns the boolean array the key maps to.
@@ -247,7 +247,7 @@ class SmartDashboard {
* non-zero value is true.
*/
static std::vector<int> GetBooleanArray(std::string_view key,
wpi::span<const int> defaultValue);
std::span<const int> defaultValue);
/**
* Put a number array in the table.
@@ -257,7 +257,7 @@ class SmartDashboard {
* @return False if the table key already exists with a different type
*/
static bool PutNumberArray(std::string_view key,
wpi::span<const double> value);
std::span<const double> value);
/**
* Gets the current value in the table, setting it if it does not exist.
@@ -267,7 +267,7 @@ class SmartDashboard {
* @returns False if the table key exists with a different type
*/
static bool SetDefaultNumberArray(std::string_view key,
wpi::span<const double> defaultValue);
std::span<const double> defaultValue);
/**
* Returns the number array the key maps to.
@@ -284,7 +284,7 @@ class SmartDashboard {
* use GetValue() instead.
*/
static std::vector<double> GetNumberArray(
std::string_view key, wpi::span<const double> defaultValue);
std::string_view key, std::span<const double> defaultValue);
/**
* Put a string array in the table.
@@ -294,7 +294,7 @@ class SmartDashboard {
* @return False if the table key already exists with a different type
*/
static bool PutStringArray(std::string_view key,
wpi::span<const std::string> value);
std::span<const std::string> value);
/**
* Gets the current value in the table, setting it if it does not exist.
@@ -304,7 +304,7 @@ class SmartDashboard {
* @returns False if the table key exists with a different type
*/
static bool SetDefaultStringArray(std::string_view key,
wpi::span<const std::string> defaultValue);
std::span<const std::string> defaultValue);
/**
* Returns the string array the key maps to.
@@ -321,7 +321,7 @@ class SmartDashboard {
* use GetValue() instead.
*/
static std::vector<std::string> GetStringArray(
std::string_view key, wpi::span<const std::string> defaultValue);
std::string_view key, std::span<const std::string> defaultValue);
/**
* Put a raw value (byte array) in the table.
@@ -330,7 +330,7 @@ class SmartDashboard {
* @param value The value that will be assigned.
* @return False if the table key already exists with a different type
*/
static bool PutRaw(std::string_view key, wpi::span<const uint8_t> value);
static bool PutRaw(std::string_view key, std::span<const uint8_t> value);
/**
* Gets the current value in the table, setting it if it does not exist.
@@ -340,7 +340,7 @@ class SmartDashboard {
* @returns False if the table key exists with a different type
*/
static bool SetDefaultRaw(std::string_view key,
wpi::span<const uint8_t> defaultValue);
std::span<const uint8_t> defaultValue);
/**
* Returns the raw value (byte array) the key maps to.
@@ -357,7 +357,7 @@ class SmartDashboard {
* concern, use GetValue() instead.
*/
static std::vector<uint8_t> GetRaw(std::string_view key,
wpi::span<const uint8_t> defaultValue);
std::span<const uint8_t> defaultValue);
/**
* Maps the specified key to the specified complex value (such as an array) in