Coverage Report

Created: 2024-09-08 06:47

/src/draco/src/draco/core/options.h
Line
Count
Source
1
// Copyright 2016 The Draco Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
//
15
#ifndef DRACO_CORE_OPTIONS_H_
16
#define DRACO_CORE_OPTIONS_H_
17
18
#include <cstdlib>
19
#include <map>
20
#include <string>
21
22
#include "draco/draco_features.h"
23
24
namespace draco {
25
26
// Class for storing generic options as a <name, value> pair in a string map.
27
// The API provides helper methods for directly storing values of various types
28
// such as ints and bools. One named option should be set with only a single
29
// data type.
30
class Options {
31
 public:
32
1.60k
  Options() = default;
33
3.20k
  ~Options() = default;
34
35
  // Merges |other_options| on top of the existing options of this instance
36
  // replacing all entries that are present in both options instances.
37
  void MergeAndReplace(const Options &other_options);
38
39
  void SetInt(const std::string &name, int val);
40
  void SetFloat(const std::string &name, float val);
41
  void SetBool(const std::string &name, bool val);
42
  void SetString(const std::string &name, const std::string &val);
43
  template <class VectorT>
44
  void SetVector(const std::string &name, const VectorT &vec) {
45
    SetVector(name, &vec[0], VectorT::dimension);
46
  }
47
  template <typename DataTypeT>
48
  void SetVector(const std::string &name, const DataTypeT *vec, int num_dims);
49
50
  // Getters will return a default value if the entry is not found. The default
51
  // value can be specified in the overloaded version of each function.
52
  int GetInt(const std::string &name) const;
53
  int GetInt(const std::string &name, int default_val) const;
54
  float GetFloat(const std::string &name) const;
55
  float GetFloat(const std::string &name, float default_val) const;
56
  bool GetBool(const std::string &name) const;
57
  bool GetBool(const std::string &name, bool default_val) const;
58
  std::string GetString(const std::string &name) const;
59
  std::string GetString(const std::string &name,
60
                        const std::string &default_val) const;
61
  template <class VectorT>
62
  VectorT GetVector(const std::string &name, const VectorT &default_val) const;
63
  // Unlike other Get functions, this function returns false if the option does
64
  // not exist, otherwise it fills |out_val| with the vector values. If a
65
  // default value is needed, it can be set in |out_val|.
66
  template <typename DataTypeT>
67
  bool GetVector(const std::string &name, int num_dims,
68
                 DataTypeT *out_val) const;
69
70
42
  bool IsOptionSet(const std::string &name) const {
71
42
    return options_.count(name) > 0;
72
42
  }
73
74
 private:
75
  // All entries are internally stored as strings and converted to the desired
76
  // return type based on the used Get* method.
77
  std::map<std::string, std::string> options_;
78
};
79
80
template <typename DataTypeT>
81
void Options::SetVector(const std::string &name, const DataTypeT *vec,
82
                        int num_dims) {
83
  std::string out;
84
  for (int i = 0; i < num_dims; ++i) {
85
    if (i > 0) {
86
      out += " ";
87
    }
88
89
// GNU STL on android doesn't include a proper std::to_string, but the libc++
90
// version does
91
#if defined(ANDROID) && !defined(_LIBCPP_VERSION)
92
    out += to_string(vec[i]);
93
#else
94
    out += std::to_string(vec[i]);
95
#endif
96
  }
97
  options_[name] = out;
98
}
99
100
template <class VectorT>
101
VectorT Options::GetVector(const std::string &name,
102
                           const VectorT &default_val) const {
103
  VectorT ret = default_val;
104
  GetVector(name, VectorT::dimension, &ret[0]);
105
  return ret;
106
}
107
108
template <typename DataTypeT>
109
bool Options::GetVector(const std::string &name, int num_dims,
110
                        DataTypeT *out_val) const {
111
  const auto it = options_.find(name);
112
  if (it == options_.end()) {
113
    return false;
114
  }
115
  const std::string value = it->second;
116
  if (value.length() == 0) {
117
    return true;  // Option set but no data is present
118
  }
119
  const char *act_str = value.c_str();
120
  char *next_str;
121
  for (int i = 0; i < num_dims; ++i) {
122
    if (std::is_integral<DataTypeT>::value) {
123
#ifdef ANDROID
124
      const int val = strtol(act_str, &next_str, 10);
125
#else
126
      const int val = static_cast<int>(std::strtol(act_str, &next_str, 10));
127
#endif
128
      if (act_str == next_str) {
129
        return true;  // End reached.
130
      }
131
      act_str = next_str;
132
      out_val[i] = static_cast<DataTypeT>(val);
133
    } else {
134
#ifdef ANDROID
135
      const float val = strtof(act_str, &next_str);
136
#else
137
      const float val = std::strtof(act_str, &next_str);
138
#endif
139
      if (act_str == next_str) {
140
        return true;  // End reached.
141
      }
142
      act_str = next_str;
143
      out_val[i] = static_cast<DataTypeT>(val);
144
    }
145
  }
146
  return true;
147
}
148
149
}  // namespace draco
150
151
#endif  // DRACO_CORE_OPTIONS_H_