diff --git a/dali/operators/audio/resample.cc b/dali/operators/audio/resample.cc index 86ed2b7d50b..70db9da10bc 100644 --- a/dali/operators/audio/resample.cc +++ b/dali/operators/audio/resample.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2022-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -97,18 +97,14 @@ type. Example:: nullptr, false); // Deprecated alias -DALI_SCHEMA(experimental__AudioResample) - .AddParent("AudioResample") - .DocStr("Legacy alias for :meth:`audio_resample`.") - .NumInput(1) - .NumOutput(1) - .MakeDocHidden() +DALI_SCHEMA_ALIAS(experimental__AudioResample, AudioResample) .Deprecate( "1.18", "AudioResample", "This operator was moved out from the experimental phase, " - "and is now a regular DALI operator. This is just an deprecated " - "alias kept for backward compatibility."); + "and is now a regular DALI operator. This is just a deprecated " + "alias kept for backward compatibility.") + .MakeDocHidden(); namespace audio { diff --git a/dali/operators/decoder/image_decoder.cc b/dali/operators/decoder/image_decoder.cc index 2e0fa7c8bce..f7ddcdc6c32 100644 --- a/dali/operators/decoder/image_decoder.cc +++ b/dali/operators/decoder/image_decoder.cc @@ -317,59 +317,42 @@ interpreted as absolute or relative coordinates, depending on the value of // Deprecated aliases -DALI_SCHEMA(ImageDecoder) - .DocStr("Legacy alias for :meth:`decoders.image`.") - .NumInput(1) - .NumOutput(1) - .AddParent("decoders__Image") - .MakeDocHidden() +DALI_SCHEMA_ALIAS(ImageDecoder, decoders__Image) .Deprecate( "1.0", "decoders__Image", R"code(In DALI 1.0 all decoders were moved into a dedicated :mod:`~nvidia.dali.fn.decoders` submodule and renamed to follow a common pattern. This is a placeholder operator with identical -functionality to allow for backward compatibility.)code"); +functionality to allow for backward compatibility.)code") + .MakeDocHidden(); // Fused -DALI_SCHEMA(ImageDecoderCrop) - .DocStr("Legacy alias for :meth:`decoders.image_crop`.") - .NumInput(1) - .NumOutput(1) - .AddParent("decoders__ImageCrop") - .MakeDocHidden() +DALI_SCHEMA_ALIAS(ImageDecoderCrop, decoders__ImageCrop) .Deprecate( "1.0", "decoders__ImageCrop", R"code(In DALI 1.0 all decoders were moved into a dedicated :mod:`~nvidia.dali.fn.decoders` submodule and renamed to follow a common pattern. This is a placeholder operator with identical -functionality to allow for backward compatibility.)code"); - -DALI_SCHEMA(ImageDecoderRandomCrop) - .DocStr("Legacy alias for :meth:`decoders.image_random_crop`.") - .NumInput(1) - .NumOutput(1) - .AddParent("decoders__ImageRandomCrop") - .MakeDocHidden() +functionality to allow for backward compatibility.)code") + .MakeDocHidden(); + +DALI_SCHEMA_ALIAS(ImageDecoderRandomCrop, decoders__ImageRandomCrop) .Deprecate( "1.0", "decoders__ImageRandomCrop", R"code(In DALI 1.0 all decoders were moved into a dedicated :mod:`~nvidia.dali.fn.decoders` submodule and renamed to follow a common pattern. This is a placeholder operator with identical -functionality to allow for backward compatibility.)code"); - +functionality to allow for backward compatibility.)code") + .MakeDocHidden(); -DALI_SCHEMA(ImageDecoderSlice) - .DocStr("Legacy alias for :meth:`decoders.image_slice`.") - .NumInput(1, 3) - .NumOutput(1) - .AddParent("decoders__ImageSlice") - .MakeDocHidden() +DALI_SCHEMA_ALIAS(ImageDecoderSlice, decoders__ImageSlice) .Deprecate( "1.0", "decoders__ImageSlice", R"code(In DALI 1.0 all decoders were moved into a dedicated :mod:`~nvidia.dali.fn.decoders` submodule and renamed to follow a common pattern. This is a placeholder operator with identical -functionality to allow for backward compatibility.)code"); +functionality to allow for backward compatibility.)code") + .MakeDocHidden(); } // namespace dali diff --git a/dali/operators/decoder/inflate/inflate.cc b/dali/operators/decoder/inflate/inflate.cc index 355f9239e10..c334ffe593c 100644 --- a/dali/operators/decoder/inflate/inflate.cc +++ b/dali/operators/decoder/inflate/inflate.cc @@ -89,10 +89,7 @@ The value is ignored if the `layout` is not specified or the input is not a sequ .OutputLayout(0, std::nullopt) .OutputNDim(0, std::nullopt); -DALI_SCHEMA(experimental__Inflate) - .AddParent("decoders__Inflate") - .NumInput(1) - .NumOutput(1) +DALI_SCHEMA_ALIAS(experimental__Inflate, decoders__Inflate) .Deprecate("2.0", "decoders__Inflate") .MakeDocHidden(); diff --git a/dali/operators/generic/resize/tensor_resize_cpu.cc b/dali/operators/generic/resize/tensor_resize_cpu.cc index 59624b2a4bf..a71569e7a03 100644 --- a/dali/operators/generic/resize/tensor_resize_cpu.cc +++ b/dali/operators/generic/resize/tensor_resize_cpu.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2022-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -46,20 +46,14 @@ DALI_SCHEMA(TensorResize) .AddParent("TensorResizeAttr"); // Deprecated alias -DALI_SCHEMA(experimental__TensorResize) - .AddParent("TensorResize") - .DocStr("Legacy alias for :meth:`tensor_resize`.") - .NumInput(1) - .NumOutput(1) - .MakeDocHidden() - .SupportVolumetric() - .AllowSequences() +DALI_SCHEMA_ALIAS(experimental__TensorResize, TensorResize) .Deprecate( "2.0", "TensorResize", "This operator was moved out from the experimental phase, " "and is now a regular DALI operator. This is just a deprecated " - "alias kept for backward compatibility."); + "alias kept for backward compatibility.") + .MakeDocHidden(); // Kept for backwards compatibility DALI_REGISTER_OPERATOR(experimental__TensorResize, tensor_resize::TensorResizeCPU, CPU); diff --git a/dali/operators/reader/file_reader_op.cc b/dali/operators/reader/file_reader_op.cc index 64a3560f3c0..0d6b77223f2 100644 --- a/dali/operators/reader/file_reader_op.cc +++ b/dali/operators/reader/file_reader_op.cc @@ -146,17 +146,13 @@ case-sensitively, otherwise case-insensitively.)", false) // Deprecated alias DALI_REGISTER_OPERATOR(FileReader, FileReader, CPU); -DALI_SCHEMA(FileReader) - .DocStr("Legacy alias for :meth:`readers.file`.") - .NumInput(0) - .NumOutput(2) // (Images, Labels) - .AddParent("readers__File") - .MakeDocHidden() +DALI_SCHEMA_ALIAS(FileReader, readers__File) .Deprecate( "1.0", "readers__File", R"code(In DALI 1.0 all readers were moved into a dedicated :mod:`~nvidia.dali.fn.readers` submodule and renamed to follow a common pattern. This is a placeholder operator with identical -functionality to allow for backward compatibility.)code"); +functionality to allow for backward compatibility.)code") + .MakeDocHidden(); } // namespace dali diff --git a/dali/operators/reader/mxnet_reader_op.cc b/dali/operators/reader/mxnet_reader_op.cc index fb6e34523d4..d0bcba04405 100644 --- a/dali/operators/reader/mxnet_reader_op.cc +++ b/dali/operators/reader/mxnet_reader_op.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2017-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -64,17 +64,13 @@ properties. // Deprecated alias DALI_REGISTER_OPERATOR(MXNetReader, MXNetReader, CPU); -DALI_SCHEMA(MXNetReader) - .DocStr("Legacy alias for :meth:`readers.mxnet`.") - .NumInput(0) - .NumOutput(2) - .AddParent("readers__MXNet") - .MakeDocHidden() +DALI_SCHEMA_ALIAS(MXNetReader, readers__MXNet) .Deprecate( "1.0", "readers__MXNet", R"code(In DALI 1.0 all readers were moved into a dedicated :mod:`~nvidia.dali.fn.readers` submodule and renamed to follow a common pattern. This is a placeholder operator with identical -functionality to allow for backward compatibility.)code"); +functionality to allow for backward compatibility.)code") + .MakeDocHidden(); } // namespace dali diff --git a/dali/operators/reader/numpy_reader_op.cc b/dali/operators/reader/numpy_reader_op.cc index db22b98de9d..2e23572afcc 100644 --- a/dali/operators/reader/numpy_reader_op.cc +++ b/dali/operators/reader/numpy_reader_op.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2020-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -238,18 +238,14 @@ Mutually exclusive with ``dont_use_mmap=False``.)code", // Deprecated alias DALI_REGISTER_OPERATOR(NumpyReader, NumpyReaderCPU, CPU); -DALI_SCHEMA(NumpyReader) - .DocStr("Legacy alias for :meth:`readers.numpy`.") - .NumInput(0) - .NumOutput(1) // (Arrays) - .AddParent("readers__Numpy") - .MakeDocHidden() +DALI_SCHEMA_ALIAS(NumpyReader, readers__Numpy) .Deprecate( "1.0", "readers__Numpy", R"code(In DALI 1.0 all readers were moved into a dedicated :mod:`~nvidia.dali.fn.readers` submodule and renamed to follow a common pattern. This is a placeholder operator with identical -functionality to allow for backward compatibility.)code"); +functionality to allow for backward compatibility.)code") + .MakeDocHidden(); NumpyReaderCPU::~NumpyReaderCPU() { // Stop the prefetch thread as it uses the thread pool from this class. So before we can diff --git a/dali/operators/reader/sequence_reader_op.cc b/dali/operators/reader/sequence_reader_op.cc index cfcb05d2953..1910812ce8a 100644 --- a/dali/operators/reader/sequence_reader_op.cc +++ b/dali/operators/reader/sequence_reader_op.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2018-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -90,18 +90,13 @@ For reading video sequences, one of :meth:`nvidia.dali.fn.readers.video`, // Deprecated alias DALI_REGISTER_OPERATOR(SequenceReader, SequenceReader, CPU); -DALI_SCHEMA(SequenceReader) - .DocStr("Legacy alias for :meth:`readers.sequence`.") - .NumInput(0) - .NumOutput(1) // ([Frames]) - .AllowSequences() - .AddParent("readers__Sequence") - .MakeDocHidden() +DALI_SCHEMA_ALIAS(SequenceReader, readers__Sequence) .Deprecate( "1.0", "readers__Sequence", R"code(In DALI 1.0 all readers were moved into a dedicated :mod:`~nvidia.dali.fn.readers` submodule and renamed to follow a common pattern. This is a placeholder operator with identical -functionality to allow for backward compatibility.)code"); +functionality to allow for backward compatibility.)code") + .MakeDocHidden(); } // namespace dali diff --git a/dali/operators/reader/tfrecord_reader_op.cc b/dali/operators/reader/tfrecord_reader_op.cc index fcb3e8c8d93..9ba99ffa8a7 100644 --- a/dali/operators/reader/tfrecord_reader_op.cc +++ b/dali/operators/reader/tfrecord_reader_op.cc @@ -134,16 +134,14 @@ functionality to allow for backward compatibility.)code"); // Deprecated alias -DALI_SCHEMA(TFRecordReader) - .DocStr("Legacy alias for :meth:`readers.tfrecord`.") - .AddParent("readers__TFRecord") - .MakeDocHidden() +DALI_SCHEMA_ALIAS(TFRecordReader, readers__TFRecord) .Deprecate( "1.0", "readers__TFRecord", R"code(In DALI 1.0 all readers were moved into a dedicated :mod:`~nvidia.dali.fn.readers` submodule and renamed to follow a common pattern. This is a placeholder operator with identical -functionality to allow for backward compatibility.)code"); +functionality to allow for backward compatibility.)code") + .MakeDocHidden(); void TFRecordReader::Prefetch() { // We actually prepare the next batch diff --git a/dali/operators/video/decoder/video_decoder_cpu.cc b/dali/operators/video/decoder/video_decoder_cpu.cc index 9b376da2368..51198a9221e 100644 --- a/dali/operators/video/decoder/video_decoder_cpu.cc +++ b/dali/operators/video/decoder/video_decoder_cpu.cc @@ -198,18 +198,14 @@ apart or starting playback from a frame deep into the video.)code", .OutputDType(0, DALI_UINT8) .OutputLayout(0, "FHWC"); -DALI_SCHEMA(experimental__decoders__Video) - .AddParent("decoders__Video") - .DocStr("Legacy alias for :meth:`decoders.video`.") - .NumInput(1) - .NumOutput(1) - .MakeDocHidden() +DALI_SCHEMA_ALIAS(experimental__decoders__Video, decoders__Video) .Deprecate( "2.0", "decoders__Video", "This operator was moved out from the experimental phase, " "and is now a regular DALI operator. This is just a deprecated " - "alias kept for backward compatibility."); + "alias kept for backward compatibility.") + .MakeDocHidden(); class VideoDecoderCpu : public VideoDecoderBase { public: diff --git a/dali/pipeline/operator/op_schema.cc b/dali/pipeline/operator/op_schema.cc index 55db17eabdb..8a87a669a90 100644 --- a/dali/pipeline/operator/op_schema.cc +++ b/dali/pipeline/operator/op_schema.cc @@ -27,11 +27,20 @@ namespace dali { -std::map> &SchemaRegistry::registry() { +namespace { + +std::map> ®istry() { static std::map> schema_map; return schema_map; } +std::map> &aliases() { + static std::map> alias_map; + return alias_map; +} + +} // namespace + OpSchema &SchemaRegistry::RegisterSchema(std::string_view name) { auto &schema_map = registry(); @@ -46,20 +55,52 @@ OpSchema &SchemaRegistry::RegisterSchema(std::string_view name) { } const OpSchema &SchemaRegistry::GetSchema(std::string_view name) { - auto &schema_map = registry(); - auto it = schema_map.find(name); - if (it == schema_map.end()) + if (auto *schema = TryGetSchema(name)) + return *schema; + else throw invalid_key("Schema for operator '" + std::string(name) + "' not registered"); - - return it->second; } const OpSchema *SchemaRegistry::TryGetSchema(std::string_view name) { auto &schema_map = registry(); auto it = schema_map.find(name); - return it != schema_map.end() ? &it->second : nullptr; + if (it == schema_map.end() || !it->second.AliasFor().empty()) { + auto &alias_map = aliases(); + auto alias_it = alias_map.find(name); + if (alias_it != alias_map.end()) { + name = alias_it->second; + it = schema_map.find(name); + } + } + + if (it == schema_map.end()) + return nullptr; + + return &it->second; +} + +void SchemaRegistry::AddAlias(std::string_view alias_name, std::string_view actual_name) { + if (alias_name == actual_name) + throw std::invalid_argument("Schema name self-aliasing is forbidden"); + + auto &alias_map = aliases(); + auto previous_target_it = alias_map.find(alias_name); + if (previous_target_it != alias_map.end()) + throw std::invalid_argument(make_string("\"", alias_name, + "\" is already used as a schema alias name for \"", previous_target_it->second, "\"")); + + for (;;) { + auto redir = alias_map.find(actual_name); + if (redir == alias_map.end()) + break; + if (redir->second == alias_name) + throw std::invalid_argument("Cycle detected while adding schema alias."); + actual_name = redir->second; + } + alias_map[std::string(alias_name)] = actual_name; } + const OpSchema &OpSchema::Default() { static OpSchema default_schema(DefaultSchemaTag{}); return default_schema; @@ -380,6 +421,14 @@ OpSchema &OpSchema::Deprecate(std::string version, std::string in_favor_of, return *this; } +OpSchema &OpSchema::AliasFor(std::string_view actual_name) { + DALI_ENFORCE(alias_for_.empty(), make_string( + "The schema \"", name_, "\" is already an alias for \"", alias_for_, "\"")); + + alias_for_ = actual_name; + SchemaRegistry::AddAlias(name_, actual_name); + return *this; +} OpSchema &OpSchema::Unserializable() { serializable_ = false; @@ -826,6 +875,9 @@ const std::string &OpSchema::DeprecatedInFavorOf() const { return deprecated_in_favor_of_; } +const std::string &OpSchema::AliasFor() const { + return alias_for_; +} const std::string &OpSchema::DeprecationMessage() const { return deprecation_message_; diff --git a/dali/pipeline/operator/op_schema.h b/dali/pipeline/operator/op_schema.h index db2ade83ebe..d06901bd77a 100644 --- a/dali/pipeline/operator/op_schema.h +++ b/dali/pipeline/operator/op_schema.h @@ -416,6 +416,9 @@ class DLL_PUBLIC OpSchema { std::string in_favor_of = "", std::string explanation = ""); + /** Marks that this schema is actually just an alias */ + OpSchema &AliasFor(std::string_view actual_name); + /** Notes that this operator cannot be serialized */ OpSchema &Unserializable(); @@ -735,6 +738,9 @@ used with DALIDataType, to avoid confusion with `AddOptionalArg(name, doc, /** What operator replaced the current one. */ const std::string &DeprecatedInFavorOf() const; + /** Whether this schema is just an alias for another one */ + const std::string &AliasFor() const; + /** Additional deprecation message */ const std::string &DeprecationMessage() const; @@ -1011,6 +1017,7 @@ used with DALIDataType, to avoid confusion with `AddOptionalArg(name, doc, std::string deprecated_in_favor_of_; std::string deprecation_message_; std::string deprecation_version_; + std::string alias_for_; }; @@ -1020,10 +1027,9 @@ class SchemaRegistry { DLL_PUBLIC static const OpSchema &GetSchema(std::string_view name); DLL_PUBLIC static const OpSchema *TryGetSchema(std::string_view name); - private: - inline SchemaRegistry() {} + DLL_PUBLIC static void AddAlias(std::string_view alias_name, std::string_view actual_name); - DLL_PUBLIC static std::map> ®istry(); + SchemaRegistry() = delete; }; template @@ -1061,6 +1067,8 @@ inline T OpSchema::GetDefaultValueForArgument(std::string_view name) const { #define DALI_SCHEMA(OpName) DALI_SCHEMA_REG(OpName) #endif +#define DALI_SCHEMA_ALIAS(AliasName, OpName) DALI_SCHEMA(AliasName).AliasFor(#OpName) + } // namespace dali #endif // DALI_PIPELINE_OPERATOR_OP_SCHEMA_H_ diff --git a/dali/pipeline/operator/operator.cc b/dali/pipeline/operator/operator.cc index 3c68fc700c7..a11a15776cf 100644 --- a/dali/pipeline/operator/operator.cc +++ b/dali/pipeline/operator/operator.cc @@ -158,11 +158,11 @@ std::unique_ptr InstantiateOperator(const OpSpec &spec) { string device = spec.GetArgument("device"); // traverse devices by likelihood (gpu, cpu, mixed) if (device == "gpu") { - return GPUOperatorRegistry::Registry().Create(spec.SchemaName(), spec, &device); + return GPUOperatorRegistry::Registry().Create(spec.SchemaName(), spec, device); } else if (device == "cpu") { - return CPUOperatorRegistry::Registry().Create(spec.SchemaName(), spec, &device); + return CPUOperatorRegistry::Registry().Create(spec.SchemaName(), spec, device); } else if (device == "mixed") { - return MixedOperatorRegistry::Registry().Create(spec.SchemaName(), spec, &device); + return MixedOperatorRegistry::Registry().Create(spec.SchemaName(), spec, device); } else { DALI_FAIL("Unknown device: " + device); } diff --git a/dali/pipeline/operator/operator_factory.h b/dali/pipeline/operator/operator_factory.h index 8d1aa5c00c2..5ad72dfac40 100644 --- a/dali/pipeline/operator/operator_factory.h +++ b/dali/pipeline/operator/operator_factory.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2017-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,12 +17,14 @@ #include #include +#include #include #include #include #include #include "dali/core/common.h" +#include "dali/core/string_map.h" #include "dali/core/error_handling.h" #include "dali/pipeline/operator/op_schema.h" @@ -34,25 +36,40 @@ template class OperatorRegistry { public: typedef std::function (const OpSpec &spec)> Creator; - typedef std::unordered_map CreatorRegistry; + typedef unordered_string_map CreatorRegistry; OperatorRegistry() {} - void Register(const std::string &name, Creator creator, const std::string &devName = "") { + void Register(const std::string &name, Creator creator, std::string_view devName = "") { std::lock_guard lock(mutex_); - DALI_ENFORCE(registry_.count(name) == 0, - "Operator \"" + name + "\" already registered" + - (!devName.empty() ? (" for " + devName) : "") + "."); + DALI_ENFORCE(registry_.count(name) == 0, make_string( + "Operator \"", name, "\" already registered", + (!devName.empty() ? make_string(" for ", devName) : ""), ".")); registry_[name] = creator; } std::unique_ptr Create( - const std::string &name, const OpSpec &spec, const std::string *devName = NULL) { + std::string_view name, const OpSpec &spec, std::optional devName = {}) { std::lock_guard lock(mutex_); - auto creator_it = registry_.find(name); - DALI_ENFORCE(creator_it != registry_.end(), - "Operator \"" + name + "\" not registered" + (devName? (" for " + *devName) : "") + "."); - return registry_[name](spec); + auto it = registry_.find(name); + std::string_view lookup_name = name; + while (it == registry_.end()) { + // Maybe we got an alias? Check the schema's actual name. + if (auto *schema = SchemaRegistry::TryGetSchema(lookup_name)) { + std::string_view new_name = schema->name(); + if (new_name == lookup_name) + break; // no alias found + lookup_name = new_name; + it = registry_.find(lookup_name); + } else { + break; + } + } + DALI_ENFORCE(it != registry_.end(), make_string( + "Operator \"", name, "\" not registered", + (devName ? make_string(" for ", *devName) : ""), + ".")); + return it->second(spec); } vector RegisteredNames(bool internal_ops) { diff --git a/include/dali/core/string_map.h b/include/dali/core/string_map.h new file mode 100644 index 00000000000..cd973cf4606 --- /dev/null +++ b/include/dali/core/string_map.h @@ -0,0 +1,39 @@ +// Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef DALI_CORE_STRING_MAP_H_ +#define DALI_CORE_STRING_MAP_H_ + +#include +#include +#include +#include +#include + +namespace dali { + +struct string_hash : public std::hash { + using is_transparent = void; +}; + +template +using unordered_string_map = std::unordered_map>; + +template +using string_map = std::map>; + +} // namespace dali + +#endif // DALI_CORE_STRING_MAP_H_