Flow123d  release_2.1.0-84-g6a13a75
type_base.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file type_base.cc
15  * @brief
16  */
17 
18 #include <limits>
19 #include <ios>
20 #include <map>
21 #include <vector>
22 #include <string>
23 #include <iomanip>
24 
25 #include "system/system.hh"
26 
27 #include <boost/type_traits.hpp>
28 #include <boost/tokenizer.hpp>
29 #include <boost/algorithm/string.hpp>
30 #include <boost/functional/hash.hpp>
31 #include <boost/pointer_cast.hpp>
32 
33 
34 #include "input_type.hh"
35 #include "type_output.hh"
36 #include "type_repository.hh"
37 #include "attribute_lib.hh"
39 
40 
41 namespace Input {
42 namespace Type {
43 
44 using namespace std;
45 
46 
47 
48 /*******************************************************************
49  * implementation of TypeBase
50  */
51 
52 
53 
55 : attributes_( std::make_shared<attribute_map>() ), root_of_generic_subtree_(false),
56  generic_type_hash_(0) {}
57 
58 
59 
63 
64 
65 
67 
68 
69 bool TypeBase::is_valid_identifier(const string& key) {
70  namespace ba = boost::algorithm;
71  return ba::all( key, ba::is_lower() || ba::is_digit() || ba::is_any_of("_") );
72 }
73 
74 
75 string TypeBase::desc() const {
76  stringstream ss;
77  ss << OutputText(this);
78  return ss.str();
79 }
80 
81 
82 
84  // mark unfinished types as deleted
90 
91  // check and remove deleted types
97 }
98 
99 
100 
101  std::string TypeBase::hash_str(TypeHash hash) {
102  stringstream ss;
103  ss << "\"" << std::hex << hash << "\"";
104  return ss.str();
105 }
106 
107 
108 
109 
110 void TypeBase::add_attribute_(std::string name, json_string val) {
111  ASSERT(validate_json(val))(name)(val).error("Invalid JSON format of attribute");
112  (*attributes_)[name] = val;
113 }
114 
115 
117  try {
118  json_spirit::mValue node;
119  json_spirit::read_or_throw( str, node);
120  return true;
121  } catch (json_spirit::Error_position &e ) {
122  return false;
123  }
124 }
125 
126 
128  std::stringstream ss;
129  ss << "{";
130  for (ParameterMap::iterator it=parameter_map.begin(); it!=parameter_map.end(); it++) {
131  if (it != parameter_map.begin()) ss << "," << endl;
132  ss << "\"" << (*it).first << "\" : " << TypeBase::hash_str( (*it).second );
133  }
134  ss << "}";
135  return ss.str();
136 }
137 
139  stringstream ss;
140  ss << "[ ";
141  for (ParameterMap::iterator it=parameter_map.begin(); it!=parameter_map.end(); it++) {
142  if (it != parameter_map.begin()) ss << ", ";
143  ss << "\"" << it->first << "\"";
144  }
145  ss << " ]";
146  return ss.str();
147 }
148 
150  // check if the type is really generic (it may be non-generic even if part of a generic subtree)
151  if (parameter_map.size() > 0)
155 }
156 
157 
158 void TypeBase::copy_attributes(attribute_map other_attributes) {
159  attributes_->clear();
160  for(auto &item : other_attributes) {
161  if (item.first[0] != '_') // not internal attribute
162  attributes_->insert(item);
163  }
164 }
165 
166 
168  return FinishStatus::regular_;
169 }
170 
171 
172 bool TypeBase::is_finished() const {
173  return true;
174 }
175 
176 
177 bool TypeBase::is_closed() const {
178  return true;
179 }
180 
181 
182 string TypeBase::type_name() const {
183  return "TypeBase";
184 }
185 
186 
187 string TypeBase::class_name() const {
188  return "TypeBase";
189 }
190 
191 
193  ASSERT((finish_type != FinishStatus::none_) && (finish_type != FinishStatus::in_perform_)).error();
194  return finish_type;
195 }
196 
197 
198 bool TypeBase::operator==(const TypeBase &other) const {
199  return typeid(*this) == typeid(other);
200 }
201 
202 bool TypeBase::operator!=(const TypeBase & other) const {
203  return ! (*this == other);
204 }
205 
206 
207 
208 
209 
210 
211 
212 
213 
214 
215 std::ostream& operator<<(std::ostream& stream, const TypeBase& type) {
216  return ( stream << OutputText(&type) );
217 }
218 
219 
220 
221 /**********************************************************************************
222  * implementation of Type::Array
223  */
224 
226 {
227  TypeHash seed=0;
228  boost::hash_combine(seed, type_name());
229  boost::hash_combine(seed, data_->lower_bound_);
230  boost::hash_combine(seed, data_->upper_bound_);
231  boost::hash_combine(seed, data_->type_of_values_->content_hash() );
232  return seed;
233 }
234 
235 
237  return data_->finish(finish_type);
238 }
239 
240 
241 
242 Array::ArrayData::ArrayData(unsigned int min_size, unsigned int max_size)
243 : lower_bound_(min_size), upper_bound_(max_size), finish_status(FinishStatus::none_)
244 {}
245 
246 
248 {
249  ASSERT(finish_type != FinishStatus::none_).error();
250  ASSERT(finish_type != FinishStatus::in_perform_).error();
251  ASSERT(finish_status != FinishStatus::in_perform_).error("Recursion in the IST element: array_of_" + type_of_values_->type_name());
252 
254 
255 
257 
258  if (typeid( *(type_of_values_.get()) ) == typeid(Instance)) {
259  type_of_values_->finish(FinishStatus::generic_); // finish Instance object
260  type_of_values_ = type_of_values_->make_instance().first;
261  }
262  if ((finish_type != FinishStatus::generic_) && type_of_values_->is_root_of_generic_subtree())
263  THROW( ExcGenericWithoutInstance() << EI_Object(type_of_values_->type_name()) );
264 
265  type_of_values_->finish(finish_type);
266  ASSERT(type_of_values_->is_finished()).error();
267  if (finish_type == FinishStatus::delete_) type_of_values_.reset();
268  finish_status = finish_type;
269  return (finish_status);
270 }
271 
272 
273 
274 string Array::type_name() const {
275  return "array_of_" + data_->type_of_values_->type_name();
276 }
277 
278 
279 
280 string Array::class_name() const {
281  return "Array";
282 }
283 
284 
285 
286 bool Array::operator==(const TypeBase &other) const {
287  return typeid(*this) == typeid(other) &&
288  (*data_->type_of_values_ == static_cast<const Array *>(&other)->get_sub_type() );
289 }
290 
291 
292 
294  // Create copy of array, we can't set type from parameter vector directly (it's TypeBase that is not allowed)
295  Array arr = this->deep_copy();
296  // Replace parameter stored in type_of_values_
297  MakeInstanceReturnType inst = arr.data_->type_of_values_->make_instance(vec);
298  arr.data_->type_of_values_ = inst.first;
299  ParameterMap parameter_map = inst.second;
300  // Copy attributes
302 
303  // Set parameters as attribute
304  json_string val = this->print_parameter_map_to_json(parameter_map);
305  ASSERT(this->validate_json(val))(val).error("Invalid JSON format of attribute 'parameters'.");
306  arr.parameter_map_ = parameter_map;
307  arr.generic_type_hash_ = this->content_hash();
308 
309  return std::make_pair( std::make_shared<Array>(arr), parameter_map );
310 }
311 
312 
314  Array arr = Array(Integer()); // Type integer will be overwritten
315  arr.data_ = std::make_shared<Array::ArrayData>(*this->data_);
316  arr.data_->finish_status = FinishStatus::none_;
317  return arr;
318 }
319 
320 
321 Array::Array(std::shared_ptr<TypeBase> type, unsigned int min_size, unsigned int max_size)
322 : data_(std::make_shared<ArrayData>(min_size, max_size))
323 {
324  ASSERT_LE(min_size, max_size).error("Wrong limits for size of Input::Type::Array");
325  ASSERT(type->is_closed()).error();
326 
327  data_->type_of_values_ = type;
328 }
329 
330 
331 /// Override @p Type::TypeBase::finish_status.
333  return data_->finish_status; }
334 
335 
336 bool Array::is_finished() const {
337  return (data_->finish_status != FinishStatus::none_) && (data_->finish_status != FinishStatus::in_perform_);
338 }
339 
340 
341 /**********************************************************************************
342  * implementation and explicit instantiation of Array constructor template
343  */
344 
345 template <class ValueType>
346 Array::Array(const ValueType &type, unsigned int min_size, unsigned int max_size)
347 : Array(std::static_pointer_cast<TypeBase>( std::make_shared<ValueType>(type) ), min_size, max_size)
348 {
349  // ASSERT MESSAGE: The type of declared keys has to be a class derived from TypeBase.
350  BOOST_STATIC_ASSERT( (boost::is_base_of<TypeBase, ValueType >::value) );
351 }
352 
353 // explicit instantiation
354 
355 #define ARRAY_CONSTRUCT(TYPE) \
356 template Array::Array(const TYPE &type, unsigned int min_size, unsigned int max_size)
357 
358 ARRAY_CONSTRUCT(String);
359 ARRAY_CONSTRUCT(Integer);
360 ARRAY_CONSTRUCT(Double);
361 ARRAY_CONSTRUCT(Bool);
362 ARRAY_CONSTRUCT(FileName);
363 ARRAY_CONSTRUCT(Selection);
366 ARRAY_CONSTRUCT(Tuple);
367 ARRAY_CONSTRUCT(Abstract);
368 ARRAY_CONSTRUCT(Parameter);
369 ARRAY_CONSTRUCT(Instance);
370 
371 
372 /**********************************************************************************
373  * implementation of Type::Scalar ... and descendants.
374  */
375 
376 /**********************************************************************************
377  * implementation of Type::Bool
378  */
379 
380 
382 {
383  TypeHash seed=0;
384  boost::hash_combine(seed, type_name());
385  return seed;
386 }
387 
388 
389 string Bool::type_name() const {
390  return "Bool";
391 }
392 
393 
394 string Bool::class_name() const {
395  return "Bool";
396 }
397 
398 
400  return std::make_pair( std::make_shared<Bool>(*this), ParameterMap() );
401 }
402 
403 /**********************************************************************************
404  * implementation of Type::Integer
405  */
406 
407 Integer::Integer(int lower_bound, int upper_bound)
408 : lower_bound_(lower_bound), upper_bound_(upper_bound)
409 {}
410 
411 
412 
414 {
415  TypeHash seed=0;
416  boost::hash_combine(seed, type_name());
417  boost::hash_combine(seed, lower_bound_);
418  boost::hash_combine(seed, upper_bound_);
419  return seed;
420 }
421 
422 
423 
424 bool Integer::match(std::int64_t value) const {
425  return ( value >=lower_bound_ && value <= upper_bound_);
426 }
427 
428 
429 
430 string Integer::type_name() const {
431  return "Integer";
432 }
433 
434 
435 string Integer::class_name() const {
436  return "Integer";
437 }
438 
439 
441  return std::make_pair( std::make_shared<Integer>(*this), ParameterMap() );
442 }
443 
444 
445 /**********************************************************************************
446  * implementation of Type::Double
447  */
448 
449 
450 Double::Double(double lower_bound, double upper_bound)
451 : lower_bound_(lower_bound), upper_bound_(upper_bound)
452 {}
453 
454 
456 {
457  TypeHash seed=0;
458  boost::hash_combine(seed, type_name());
459  boost::hash_combine(seed, lower_bound_);
460  boost::hash_combine(seed, upper_bound_);
461  return seed;
462 }
463 
464 
465 
466 bool Double::match(double value) const {
467  return ( value >=lower_bound_ && value <= upper_bound_);
468 }
469 
470 
471 
472 string Double::type_name() const {
473  return "Double";
474 }
475 
476 
477 string Double::class_name() const {
478  return "Double";
479 }
480 
481 
483  return std::make_pair( std::make_shared<Double>(*this), ParameterMap() );
484 }
485 
486 
487 /**********************************************************************************
488  * implementation of Type::FileName
489  */
490 
492 
493 
494 
495 FileName::FileName(enum ::FilePath::FileType type)
496 : type_(type)
497 {}
498 
499 
500 
502 {
503  return FileName(::FilePath::input_file);
504 }
505 
506 
507 
509 {
511 }
512 
513 
514 
516 {
517  TypeHash seed=0;
518  boost::hash_combine(seed, type_name());
519  boost::hash_combine(seed, type_);
520  return seed;
521 }
522 
523 
524 
525 
526 
527 string FileName::type_name() const {
528  switch (type_) {
529  case ::FilePath::input_file:
530  return "FileName_input";
531  case ::FilePath::output_file:
532  return "FileName_output";
533  default:
534  return "FileName";
535  }
536 }
537 
538 
539 string FileName::class_name() const {
540  return "FileName";
541 }
542 
543 
544 
545 bool FileName::match(const string &str) const {
546  return (type_ == ::FilePath::input_file) || (str[0] != DIR_DELIMITER); // output files can not be absolute
547 }
548 
549 
550 
552  return std::make_pair( std::make_shared<FileName>(*this), ParameterMap() );
553 }
554 
555 
556 
558  return type_;
559 }
560 
561 
562 
563 
564 bool FileName::operator==(const TypeBase &other) const
565 {
566  return typeid(*this) == typeid(other) &&
567  (type_== static_cast<const FileName *>(&other)->get_file_type() );
568 }
569 
570 
571 /**********************************************************************************
572  * implementation of Type::String
573  */
574 
575 
577 {
578  TypeHash seed=0;
579  boost::hash_combine(seed, type_name());
580  return seed;
581 }
582 
583 
584 
585 string String::type_name() const {
586  return "String";
587 }
588 
589 
590 
591 string String::class_name() const {
592  return "String";
593 }
594 
595 
596 
597 bool String::match(const string &str) const {
598  return true;
599 }
600 
601 
602 
604  return std::make_pair( std::make_shared<String>(*this), ParameterMap() );
605 }
606 
607 
608 
609 } // closing namespace Type
610 } // closing namespace Input
611 
612 
613 
bool operator==(const TypeBase &other) const override
Implements Type::TypeBase::operator== Compares also subtypes.
Definition: type_base.cc:286
bool validate_json(json_string str) const
Check if str is valid JSON string.
Definition: type_base.cc:116
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:551
static bool is_valid_identifier(const string &key)
Check that a key is valid identifier.
Definition: type_base.cc:69
std::int64_t lower_bound_
Minimal value of Integer.
Definition: type_base.hh:521
Base of classes for declaring structure of the input data.
Definition: type_base.hh:93
void set_generic_attributes(ParameterMap param_map)
Definition: type_base.cc:149
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:440
bool is_root_of_generic_subtree()
Indicates if type is marked with flag root_of_generic_subtree_.
Definition: type_base.hh:232
virtual string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:585
void copy_attributes(attribute_map other_attributes)
Definition: type_base.cc:158
static string generic_parameters()
FinishStatus finish_status
Flag specified if Array is finished.
Definition: type_base.hh:361
std::string hash_str() const
Format the hash of this type.
Definition: type_base.hh:220
bool root_of_generic_subtree_
flag is true if type should be root of generic subtree
Definition: type_base.hh:301
virtual FinishStatus finish_status() const
Returns true if the type is fully specified and ready for read access.
Definition: type_base.cc:167
string desc() const
Returns string with Type extensive documentation.
Definition: type_base.cc:75
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:381
IntFormatSpec< int, TypeSpec<'x'> > hex(int value)
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:472
virtual bool operator==(const TypeBase &other) const
Comparison of types.
Definition: type_base.cc:198
FinishStatus finish(FinishStatus finish_type=FinishStatus::regular_)
Finishes initialization of the ArrayData.
Definition: type_base.cc:247
virtual FinishStatus finish(FinishStatus finish_type=FinishStatus::regular_)
Finish method. Finalize construction of "Lazy types": Record, Selection, Abstract and generic type...
Definition: type_base.cc:192
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:576
FileType
Possible types of file.
Definition: file_path.hh:61
virtual string class_name() const
Returns an identification of the class. Useful for output of the documentation.
Definition: type_base.cc:187
std::pair< std::shared_ptr< TypeBase >, ParameterMap > MakeInstanceReturnType
Return type of make_instance methods, contains instance of generic type and map of used parameters...
Definition: type_base.hh:111
virtual bool is_finished() const
Definition: type_base.cc:172
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:527
::FilePath::FileType type_
The type of file (input or output).
Definition: type_base.hh:655
Double(double lower_bound=-std::numeric_limits< double >::max(), double upper_bound=std::numeric_limits< double >::max())
Constructor.
Definition: type_base.cc:450
Helper class that stores data of generic types.
Definition: type_generic.hh:88
#define ASSERT_LE(a, b)
Definition of comparative assert macro (Less or Equal)
Definition: asserts.hh:304
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:225
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:389
Class for declaration of the input data that are file names.
Definition: type_base.hh:611
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_base.cc:591
std::shared_ptr< attribute_map > attributes_
map of type attributes (e. g. input_type, name etc.)
Definition: type_base.hh:298
Class for declaration of the integral input data.
Definition: type_base.hh:483
void add_attribute_(std::string name, json_string val)
Add attribute of given name to attribute map.
Definition: type_base.cc:110
ArrayData(unsigned int min_size, unsigned int max_size)
Constructor.
Definition: type_base.cc:242
Class for declaration of inputs sequences.
Definition: type_base.hh:339
void read_or_throw(const std::string &s, mValue &value)
double upper_bound_
Maximal value of Integer.
Definition: type_base.hh:569
static constexpr bool value
Definition: json.hpp:87
static TypeRepository & get_instance()
Return singleton instance of class.
ParameterMap parameter_map_
map of parameters if type is part of generic subtree
Definition: type_base.hh:307
std::shared_ptr< ArrayData > data_
Handle to the actual array data.
Definition: type_base.hh:429
bool match(std::int64_t value) const
Check valid value of Integer.
Definition: type_base.cc:424
std::map< std::string, TypeHash > ParameterMap
Defines map of used parameters.
Definition: type_base.hh:109
void reset_deleted_types()
Reset and remove types marked as deleted during finish.
std::int64_t upper_bound_
Maximal value of Integer.
Definition: type_base.hh:522
TypeBase()
The default constructor.
Definition: type_base.cc:54
static FileName input()
The factory function for declaring type FileName for input files.
Definition: type_base.cc:501
bool match(double value) const
Returns true if the given integer value conforms to the Type::Double bounds.
Definition: type_base.cc:466
static string root_of_generic_subtree()
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:413
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:430
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:293
FinishStatus finish(FinishStatus finish_type=FinishStatus::regular_) override
Finishes initialization of the Array type because of lazy evaluation of type_of_values.
Definition: type_base.cc:236
::FilePath::FileType get_file_type() const
Returns type of the file input/output.
Definition: type_base.cc:557
virtual bool is_closed() const
Returns true if the type is closed.
Definition: type_base.cc:177
bool operator!=(const TypeBase &other) const
Comparison of types.
Definition: type_base.cc:202
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:515
virtual MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:603
bool match(const string &str) const override
Checks relative output paths.
Definition: type_base.cc:545
string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_base.cc:539
FileName()
Forbids default constructor.
Definition: type_base.cc:491
virtual bool match(const string &value) const
Particular descendants can check validity of the string.
Definition: type_base.cc:597
TypeHash generic_type_hash_
hash string of generic type if type is derived, or empty string
Definition: type_base.hh:304
json_string print_parameter_map_to_json(ParameterMap parameter_map) const
Create JSON output from parameter_map formatted as value of attribute.
Definition: type_base.cc:127
bool is_finished() const override
Override Type::TypeBase::is_finished.
Definition: type_base.cc:336
std::shared_ptr< TypeBase > type_of_values_
Type of Array.
Definition: type_base.hh:355
virtual string type_name() const
Returns an identification of the type. Useful for error messages.
Definition: type_base.cc:182
Actual data of the Array.
Definition: type_base.hh:347
#define DIR_DELIMITER
Definition: system.hh:44
double lower_bound_
Minimal value of Integer.
Definition: type_base.hh:568
std::string json_string
String stored in JSON format.
Definition: type_base.hh:99
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:399
string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_base.cc:435
std::ostream & operator<<(std::ostream &stream, const TypeBase &type)
For convenience we provide also redirection operator for output documentation of Input:Type classes...
Definition: type_base.cc:215
bool operator==(const TypeBase &other) const override
Comparison of types.
Definition: type_base.cc:564
string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_base.cc:477
static void delete_unfinished_types()
Finishes and marks all types registered in type repositories and unused in IST.
Definition: type_base.cc:83
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:455
Class for create text documentation.
Definition: type_output.hh:204
ARRAY_CONSTRUCT(String)
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:274
virtual ~TypeBase()
Destructor.
Definition: type_base.cc:66
Array deep_copy() const
Create deep copy of Array.
Definition: type_base.cc:313
Integer(int lower_bound=std::numeric_limits< int >::min(), int upper_bound=std::numeric_limits< int >::max())
Constructor.
Definition: type_base.cc:407
static FileName output()
The factory function for declaring type FileName for input files.
Definition: type_base.cc:508
string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_base.cc:280
json_string print_parameter_map_keys_to_json(ParameterMap param_map) const
Definition: type_base.cc:138
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:96
Array()
Forbids default constructor in order to prevent empty data_.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:45
FinishStatus finish_status() const override
Override Type::TypeBase::finish_status.
Definition: type_base.cc:332
friend class Record
Definition: type_base.hh:310
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:482
void finish(Type::FinishStatus finish_type)
Finish all stored types.
string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_base.cc:394