diff options
| author | Dustin Graves <dustin@lunarg.com> | 2016-07-22 13:19:02 -0600 |
|---|---|---|
| committer | Mark Lobodzinski <mark@lunarg.com> | 2016-08-24 13:20:40 -0600 |
| commit | 5f6626ceebc4f1dec8b8508c78d3e33523f42f06 (patch) | |
| tree | 0babb824a02022d760b2bc1899ba49c96c8e46ff | |
| parent | f1fd975cf89d59548ee8c5e65bc4cd7a58af3c9c (diff) | |
| download | usermoji-5f6626ceebc4f1dec8b8508c78d3e33523f42f06.tar.xz | |
layers: Add parameter name formatting class
Add a custom parameter name class with support for deferred
formatting of names containing array subscripts. The class
stores a format string and a vector of index values, and
performs string formatting when an accessor function is called
to retrieve the name string.
Change-Id: I941116a16b6fa19e63314cbeab33223e0fa072d3
| -rw-r--r-- | layers/parameter_name.h | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/layers/parameter_name.h b/layers/parameter_name.h new file mode 100644 index 00000000..b788584e --- /dev/null +++ b/layers/parameter_name.h @@ -0,0 +1,148 @@ +/* Copyright (c) 2016 The Khronos Group Inc. + * Copyright (c) 2016 Valve Corporation + * Copyright (c) 2016 LunarG, Inc. + * Copyright (c) 2016 Google Inc. + * + * 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 PARAMETER_NAME_H +#define PARAMETER_NAME_H + +#include <cassert> +#include <sstream> +#include <string> +#include <vector> + +/** + * Parameter name string supporting deferred formatting for array subscripts. + * + * Custom parameter name class with support for deferred formatting of names containing array subscripts. The class stores + * a format string and a vector of index values, and performs string formatting when an accessor function is called to + * retrieve the name string. This class was primarily designed to be used with validation functions that receive a parameter name + * string and value as arguments, and print an error message that includes the parameter name when the value fails a validation + * test. Using standard strings with these validation functions requires that parameter names containing array subscripts be + * formatted before each validation function is called, performing the string formatting even when the value passes validation + * and the string is not used: + * sprintf(name, "pCreateInfo[%d].sType", i); + * validate_stype(name, pCreateInfo[i].sType); + * + * With the ParameterName class, a format string and a vector of format values are stored by the ParameterName object that is + * provided to the validation function. String formatting is then performed only when the validation function retrieves the + * name string from the ParameterName object: + * validate_stype(ParameterName("pCreateInfo[%i].sType", IndexVector{ i }), pCreateInfo[i].sType); + */ +class ParameterName { + public: + /// Container for index values to be used with parameter name string formatting. + typedef std::vector<size_t> IndexVector; + + /// Format specifier for the parameter name string, to be replaced by an index value. The parameter name string must contain + /// one format specifier for each index value specified. + const std::string IndexFormatSpecifier = "%i"; + + public: + /** + * Construct a ParameterName object from a string literal, without formatting. + * + * @param source Paramater name string without format specifiers. + * + * @pre The source string must not contain the %i format specifier. + */ + ParameterName(const char *source) : source_(source) { assert(IsValid()); } + + /** + * Construct a ParameterName object from a std::string object, without formatting. + * + * @param source Paramater name string without format specifiers. + * + * @pre The source string must not contain the %i format specifier. + */ + ParameterName(const std::string &source) : source_(source) { assert(IsValid()); } + + /** + * Construct a ParameterName object from a std::string object, without formatting. + * + * @param source Paramater name string without format specifiers. + * + * @pre The source string must not contain the %i format specifier. + */ + ParameterName(const std::string &&source) : source_(std::move(source)) { assert(IsValid()); } + + /** + * Construct a ParameterName object from a std::string object, with formatting. + * + * @param source Paramater name string with format specifiers. + * @param args Array index values to be used for formatting. + * + * @pre The number of %i format specifiers contained by the source string must match the number of elements contained + * by the index vector. + */ + ParameterName(const std::string &source, const IndexVector &args) : source_(source), args_(args) { assert(IsValid()); } + + /** + * Construct a ParameterName object from a std::string object, with formatting. + * + * @param source Paramater name string with format specifiers. + * @param args Array index values to be used for formatting. + * + * @pre The number of %i format specifiers contained by the source string must match the number of elements contained + * by the index vector. + */ + ParameterName(const std::string &&source, const IndexVector &&args) : source_(std::move(source)), args_(std::move(args)) { + assert(IsValid()); + } + + /// Retrive the formatted name string. + std::string get_name() const { return (args_.empty()) ? source_ : Format(); } + + private: + /// Replace the %i format specifiers in the source string with the values from the index vector. + std::string Format() const { + std::string::size_type current = 0; + std::string::size_type last = 0; + std::stringstream format; + + for (size_t index : args_) { + current = source_.find(IndexFormatSpecifier, last); + if (current == std::string::npos) { + break; + } + format << source_.substr(last, (current - last)) << index; + last = current + IndexFormatSpecifier.length(); + } + + format << source_.substr(last, std::string::npos); + + return format.str(); + } + + /// Check that the number of %i format specifiers in the source string matches the number of elements in the index vector. + bool IsValid() { + // Count the number of occurances of the format specifier + uint32_t count = 0; + std::string::size_type pos = source_.find(IndexFormatSpecifier); + + while (pos != std::string::npos) { + ++count; + pos = source_.find(IndexFormatSpecifier, pos + 1); + } + + return (count == args_.size()); + } + + private: + std::string source_; ///< Format string. + IndexVector args_; ///< Array index values for formatting. +}; + +#endif // PARAMETER_NAME_H |
