This file is indexed.

/usr/include/mathic/NameFactory.h is in libmathic-dev 1.0~git20160320-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#ifndef MATHIC_NAME_FACTORY_GUARD
#define MATHIC_NAME_FACTORY_GUARD

#include "stdinc.h"
#include "error.h"
#include <vector>
#include <string>
#include <algorithm>
#include <memory>

namespace mathic {
  /** A NameFactory takes a name and then creates an instance of a class
   that has been previously registered under that name. This is done
   in a general way using templates.

   None of this is very efficient currently. However, the interface can be
   implemented much more efficiently if that becomes necessary.
  */
  template<class AbstractProduct>
  class NameFactory {
   public:
    /** @param abstractName The name for those things that are being
     generated in general. Used for error messages. */
    NameFactory(const char* abstractName): _abstractName(abstractName) {}

    typedef std::unique_ptr<AbstractProduct> (*FactoryFunction)();
    void registerProduct(const std::string& name, FactoryFunction function);

    /** Calls the function registered to the parameter name and returns
     the result. Returns null if name has not been registered. */
    std::unique_ptr<AbstractProduct>
      createNullOnUnknown(const std::string& name) const;

    /** Calls the function registered to the parameter name and returns
     the result. Throws an exception if name has not been registered. */
    std::unique_ptr<AbstractProduct> create(const std::string& name) const;

    /** Inserts into names all registered names that have the indicated
     prefix in lexicographic increasing order. */
    void namesWithPrefix
      (const std::string& prefix, std::vector<std::string>& names) const;

    /** Returns the name of the kinds of things being created. */
    std::string abstractProductName() const;

    /** Returns true if no names have been registered. */
    bool empty() const;

   private:
    typedef std::pair<std::string, FactoryFunction> Pair;
    typedef typename std::vector<Pair>::const_iterator const_iterator;
    std::vector<Pair> _pairs;
    const std::string _abstractName;
  };

  /** Registers the given name to a function that
    default-constructs a ConcreteProduct. */
  template<class ConcreteProduct, class AbstractProduct>
  void nameFactoryRegister
    (NameFactory<AbstractProduct>& factory, const std::string& name);

  /** Registers the name ConcreteProduct::staticName() to a function that
    default-constructs a ConcreteProduct. */
  template<class ConcreteProduct, class AbstractProduct>
  void nameFactoryRegister
    (NameFactory<AbstractProduct>& factory);

  /** Registers the string returned by ConcreteProduct::staticName()
   to a function that default-constructs a ConcreteProduct. */
  template<class ConcreteProduct, class AbstractProduct>
  void nameFactoryRegister(NameFactory<AbstractProduct>& factory);

  /** Creates the unique product that has the indicated prefix, or
   creates the actual product that has name equal to the indicated
   prefix. Exceptions thrown are as for uniqueNamesWithPrefix(). */
  template<class AbstractProduct>
  std::unique_ptr<AbstractProduct> createWithPrefix
  (const NameFactory<AbstractProduct>& factory, const std::string& prefix);

  /** Returns the unique product name that has the indicated prefix, or
   return prefix itself if it is the actual name of a product.

   @exception UnknownNameException If no product has the indicated
   prefix.

   @exception AmbiguousNameException If more than one product has the
   indicated prefix and the prefix is not the actual name of any
   product. */
  template<class AbstractProduct>
  std::string uniqueNameWithPrefix
  (const NameFactory<AbstractProduct>& factory, const std::string& prefix);


  // **************************************************************
  // These implementations have to be included here due
  // to being templates.

  template<class AbstractProduct>
  std::unique_ptr<AbstractProduct> NameFactory<AbstractProduct>::
  createNullOnUnknown(const std::string& name) const {
    for (const_iterator it = _pairs.begin(); it != _pairs.end(); ++it)
      if (it->first == name)
        return it->second();
    return std::unique_ptr<AbstractProduct>();
  }

  template<class AbstractProduct>
  std::unique_ptr<AbstractProduct> NameFactory<AbstractProduct>::
  create(const std::string& name) const {
    std::unique_ptr<AbstractProduct> product = createNullOnUnknown(name);
    if (product.get() == 0)
      throwError<UnknownNameException>(
        "Unknown " + abstractProductName() + " \"" + name + "\".");
    return product;
  }

  template<class AbstractProduct>
  void NameFactory<AbstractProduct>::
  registerProduct(const std::string& name, FactoryFunction function) {
    MATHIC_ASSERT(createNullOnUnknown(name).get() == 0); // no duplicate names
    _pairs.push_back(Pair(name, function));
  }

  template<class AbstractProduct>
  void NameFactory<AbstractProduct>::namesWithPrefix(
    const std::string& prefix,
    std::vector<std::string>& names
  ) const {
    for (const_iterator it = _pairs.begin(); it != _pairs.end(); ++it)
      if (it->first.compare(0, prefix.size(), prefix) == 0)
        names.push_back(it->first);
    std::sort(names.begin(), names.end());
  }

  template<class AbstractProduct>
  bool NameFactory<AbstractProduct>::empty() const {
    return _pairs.empty();
  }

  template<class AbstractProduct>
  std::string NameFactory<AbstractProduct>::abstractProductName() const {
    return _abstractName;
  }

  template<class ConcreteProduct, class AbstractProduct>
  void nameFactoryRegister(NameFactory<AbstractProduct>& factory) {
    nameFactoryRegister<ConcreteProduct, AbstractProduct>
      (factory, ConcreteProduct::staticName());
  }

  template<class ConcreteProduct, class AbstractProduct>
  void nameFactoryRegister
    (NameFactory<AbstractProduct>& factory, const std::string& name) {
    // work-around for no local functions in old C++
    struct HoldsFunction {
      static std::unique_ptr<AbstractProduct> createConcreteProduct() {
        return std::unique_ptr<AbstractProduct>(new ConcreteProduct());
      }
    };
    factory.registerProduct(name, HoldsFunction::createConcreteProduct);
  }

  template<class AbstractProduct>
  std::unique_ptr<AbstractProduct> createWithPrefix
  (const NameFactory<AbstractProduct>& factory, const std::string& prefix) {
    return factory.createNullOnUnknown(uniqueNameWithPrefix(factory, prefix));
  }

  template<class AbstractProduct>
  std::string uniqueNameWithPrefix
  (const NameFactory<AbstractProduct>& factory, const std::string& prefix) {
    std::vector<std::string> names;
    factory.namesWithPrefix(prefix, names);

    // if exact string found, then use that one even if there are other
    // prefix matches.
    if (std::find(names.begin(), names.end(), prefix) != names.end()) {
      names.clear();
      names.push_back(prefix);
    }

    if (names.empty()) {
      throwError<UnknownNameException>
        ("No " + factory.abstractProductName() +
         " has the prefix \"" + prefix + "\".");
    }

    if (names.size() >= 2) {
      std::string errorMsg = "More than one " + factory.abstractProductName() +
        " has prefix \"" + prefix + "\":\n ";
      for (size_t name = 0; name < names.size(); ++name)
        errorMsg += ' ' + names[name];
      throwError<AmbiguousNameException>(errorMsg);
    }

    MATHIC_ASSERT(names.size() == 1);
    return names.back();
  }
}

#endif