libabigail/include/abg-interned-str.h
Matthias Maennich 86c06ad684 Consistently use std::unique_ptr for private implementations (pimpl)
In the absence of non-refcounting smart pointers before C++11,
std::shared_ptr was commonly used instead. Having bumped the standard to
C++11, allows us to use std::unique_ptr consistently avoiding any costs
involved with shared_ptr ref counting. Hence do that and add default
virtual destructors where required.

	* include/abg-comparison.h (diff_maps): use unique_ptr for priv_
	(diff_context): Likewise.
	(diff_traversable_base): Likewise.
	(type_diff_base): Likewise.
	(decl_diff_base): Likewise.
	(distinct_diff): Likewise.
	(var_diff): Likewise.
	(pointer_diff): Likewise.
	(reference_diff): Likewise.
	(array_diff): Likewise.
	(qualified_type_diff): Likewise.
	(enum_diff): Likewise.
	(class_or_union_diff): Likewise.
	(class_diff): Likewise.
	(base_diff): Likewise.
	(scope_diff): Likewise.
	(fn_parm_diff): Likewise.
	(function_type_diff): Likewise.
	(function_decl_diff): Likewise.
	(typedef_diff): Likewise.
	(translation_unit_diff): Likewise.
	(diff_stats): Likewise.
	(diff_node_visitor): Likewise.
	* include/abg-corpus.h (corpus): Likewise.
	(exported_decls_builder): Likewise.
	(corpus_group): Likewise.
	* include/abg-ini.h (property): Likewise.
	(property_value): Likewise.
	(string_property_value): Likewise.
	(list_property_value): Likewise.
	(tuple_property_value): Likewise.
	(simple_property): Likewise.
	(list_property): Likewise.
	(tuple_property): Likewise.
	(config): Likewise.
	(section): Likewise.
	(function_call_expr): Likewise.
	* include/abg-interned-str.h (interned_string_pool): Likewise.
	* include/abg-ir.h (environment): Likewise.
	(location_manager): Likewise.
	(type_maps): Likewise.
	(translation_unit): Likewise.
	(elf_symbol::version): Likewise.
	(type_or_decl_base): Likewise.
	(scope_decl): Likewise.
	(qualified_type_def): Likewise.
	(pointer_type_def): Likewise.
	(array_type_def): Likewise.
	(subrange_type): Likewise.
	(enum_type_decl): Likewise.
	(enum_type_decl::enumerator): Likewise.
	(typedef_decl): Likewise.
	(dm_context_rel): Likewise.
	(var_decl): Likewise.
	(function_decl::parameter): Likewise.
	(function_type): Likewise.
	(method_type): Likewise.
	(template_decl): Likewise.
	(template_parameter): Likewise.
	(type_tparameter): Likewise.
	(non_type_tparameter): Likewise.
	(template_tparameter): Likewise.
	(type_composition): Likewise.
	(function_tdecl): Likewise.
	(class_tdecl): Likewise.
	(class_decl::base_spec): Likewise.
	(ir_node_visitor): Likewise.
	* include/abg-suppression.h (suppression_base): Likewise.
	(type_suppression::insertion_range): Likewise.
	(type_suppression::insertion_range::boundary): Likewise.
	(type_suppression::insertion_range::integer_boundary): Likewise.
	(type_suppression::insertion_range::fn_call_expr_boundary): Likewise.
	(function_suppression): Likewise.
	(function_suppression::parameter_spec): Likewise.
	(file_suppression): Likewise.
	* include/abg-tools-utils.h (temp_file): Likewise.
	(timer): Likewise.
	* include/abg-traverse.h (traversable_base): Likewise.
	* include/abg-workers.h (queue): Likewise.
	* src/abg-comparison.cc (diff_context): add default destructor.
	(diff_maps): Likewise.
	(corpus_diff): Likewise.
	(diff_node_visitor): Likewise.
	(class_or_union_diff::get_priv): adjust return type.
	(class_diff::get_priv): adjust return type.
	* src/abg-corpus.cc (corpus): add default destructor.
	* src/abg-ir.cc (location_manager): Likewise.
	(type_maps): Likewise.
	(elf_symbol::version): Likewise.
	(array_type_def::subrange_type): Likewise.
	(enum_type_decl::enumerator): Likewise.
	(function_decl::parameter): Likewise.
	(class_decl::base_spec): Likewise.
	(ir_node_visitor): Likewise.

Signed-off-by: Matthias Maennich <maennich@google.com>
2021-07-16 11:16:47 +02:00

254 lines
6.3 KiB
C++

// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -*- Mode: C++ -*-
//
// Copyright (C) 2016-2020 Red Hat, Inc.
//
// Author: Dodji Seketeli
/// @file
///
/// Declaration of types pertaining to the interned string pool used
/// throughout Libabigail, for performance reasons.
///
/// For the record, the concept of the String Interning method is
/// explained at https://en.wikipedia.org/wiki/String_interning.
#ifndef __ABG_INTERNED_STR_H__
#define __ABG_INTERNED_STR_H__
#include <functional>
#include <memory>
#include <ostream>
#include <string>
#include <unordered_set>
namespace abigail
{
// Inject some std types into this namespace.
using std::unordered_set;
using std::string;
using std::ostream;
/// The abstraction of an interned string.
///
/// It's a wrapper around a pointer to a std::string, along with a set
/// of method that helps make this string integrate with std::string
/// seamlessly. For instance, the type provides equality operators
/// that help compare it against std::string.
///
/// Note that this @ref interned_string type is design to have the
/// same size as a pointer to a string.
class interned_string
{
std::string* raw_;
/// Constructor.
///
/// @param raw the pointer to string that this interned_string
/// wraps.
interned_string(string* raw)
: raw_(raw)
{}
public:
/// Default constructor.
///
/// Constructs an empty pointer to string.
interned_string()
: raw_()
{}
/// Copy constructor.
///
/// @param o the other instance to copy from.
interned_string(const interned_string& o)
{raw_ = o.raw_;}
/// Assignment operator.
///
/// @param o the other instance to assign to the current one.
interned_string&
operator=(const interned_string& o)
{
raw_ = o.raw_;
return *this;
}
/// Clear the string.
void
clear()
{raw_ = 0;}
/// Test if the current instance of @ref interned_string is empty.
///
/// @return true iff the currentisntance of @ref interned_string is
/// empty.
bool
empty() const
{return !raw_;}
/// Return the underlying pointer to std::string that this
/// interned_string wraps.
///
/// @return a pointer to the underlying std::string, or 0 if this
/// interned_string is empty.
const string*
raw() const
{return raw_;}
/// Compare the current instance of @ref interned_string against
/// another instance of @ref interned_string.
///
/// Note that this comparison is done in O(1), because it compares
/// the pointer values of the two underlying pointers to std::string
/// held by each instances of @ref interned_string.
///
/// @param o the other @ref interned_string to compare against.
///
/// @return true iff the current instance equals @p o.
bool
operator==(const interned_string& o) const
{return raw_ == o.raw_;}
/// Inequality operator.
///
/// @param o the other @ref interned_string to compare the current
/// instance against.
///
/// @return true iff the current instance is different from the @p
/// o.
bool
operator!=(const interned_string& o) const
{return !operator==(o);}
/// Compare the current instance of @ref interned_string against
/// an instance of std::string.
///
/// Note that this comparison is done in O(N), N being the size (in
/// number of characters) of the strings being compared.
///
/// @param o the instance of std::string to compare against.
///
/// @return true iff the current instance equals @p o.
bool
operator==(const string& o) const
{
if (raw_)
return *raw_ == o;
return o.empty();
}
/// Inequality operator.
///
/// Takes the current instance of @ref interned_string and an
/// instance of std::string.
///
/// @param o the instance of std::string to compare the current
/// instance of @ref interned_string against.
///
/// @return true if the current instance of @ref interned_string is
/// different from @p o.
bool
operator!=(const string& o) const
{return ! operator==(o);}
/// "Less than" operator.
///
/// Lexicographically compares the current instance of @ref
/// interned_string against another instance.
///
/// @param o the other instance of @ref interned_string to compare
/// against.
///
/// @return true iff the current instance of interned_string is
/// lexicographycally less than the string @p o.
bool
operator<(const interned_string& o) const
{return static_cast<string>(*this) < static_cast<std::string>(o);}
/// Conversion operator to string.
///
/// @return the underlying string this instance refers too.
operator string() const
{
if (!raw_)
return "";
return *raw_;
}
friend class interned_string_pool;
}; // end class interned_string
bool
operator==(const string& l, const interned_string& r);
bool
operator!=(const string& l, const interned_string& r);
ostream&
operator<<(ostream& o, const interned_string& s);
string
operator+(const interned_string& s1,const string& s2);
string
operator+(const string& s1, const interned_string& s2);
/// A functor to hash instances of @ref interned_string.
struct hash_interned_string
{
/// The hash operator.
///
/// It's super fast because hashing an interned string amounts to
/// hashing the pointer to it's underlying string. It's because
/// every distinct string is present only in one copy in the
/// environment.
///
/// @param s the instance of @ref interned_string to hash.
///
/// @return the returned hash value.
size_t
operator()(const interned_string& s) const
{
std::hash<size_t> hash_size_t;
return hash_size_t(reinterpret_cast<size_t>(s.raw()));
}
}; // end struct hash_interned_string
/// The interned string pool.
///
/// This is where all the distinct strings represented by the interned
/// strings leave. The pool is the actor responsible for creating
/// interned strings.
class interned_string_pool
{
struct priv;
std::unique_ptr<priv> priv_;
public:
interned_string_pool();
interned_string
create_string(const std::string&);
bool
has_string(const char* s) const;
const char*
get_string(const char* s) const;
~interned_string_pool();
}; // end class interned_string_pool
/// Convenience typedef for a set of @ref interned_string
typedef unordered_set<interned_string,
hash_interned_string> interned_string_set_type;
} // end namespace abigail
#endif // __ABG_INTERNED_STR_H__