Skip to content

ID_* symbols are now constexpr #2133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions src/util/dstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Author: Daniel Kroening, [email protected]

/// \ref dstringt has one field, an unsigned integer \ref no which is an index
/// into a static table of strings. This makes it expensive to create a new
/// string(because you have to look through the whole table to see if it is
/// string (because you have to look through the whole table to see if it is
/// already there, and add it if it isn't) but very cheap to compare strings
/// (just compare the two integers). It also means that when you have lots of
/// copies of the same string you only have to store the whole string once,
Expand All @@ -30,10 +30,7 @@ Author: Daniel Kroening, [email protected]
/// `irep_idt` and `irep_namet` are typedef-ed to \ref dstringt in irep.h unless
/// `USE_STD_STRING` is set.
///
///
/// Note: Marked final to disable inheritance. No virtual destructor, so
/// runtime-polymorphic use would be unsafe.
class dstringt final
class dstringt
{
public:
// this is safe for static objects
Expand Down Expand Up @@ -183,8 +180,8 @@ class dstringt final
return as_string().end();
}

private:
#ifdef __GNUC__
protected:
#ifdef __GNUC__
constexpr
#endif
explicit dstringt(unsigned _no):no(_no)
Expand Down
3 changes: 1 addition & 2 deletions src/util/irep.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ Author: Daniel Kroening, [email protected]
#endif

#ifdef USE_DSTRING
typedef dstringt irep_idt;
typedef dstringt irep_namet;
typedef irep_idt irep_namet;
// NOLINTNEXTLINE(readability/identifiers)
typedef dstring_hash irep_id_hash;
#else
Expand Down
19 changes: 2 additions & 17 deletions src/util/irep_ids.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,15 @@ const char *irep_ids_table[]=

#ifdef USE_DSTRING

enum class idt:unsigned
{
#define IREP_ID_ONE(the_id) id_##the_id,
#define IREP_ID_TWO(the_id, str) id_##the_id,

#include "irep_ids.def" // NOLINT(build/include)
};

#define IREP_ID_ONE(the_id) \
const dstringt ID_##the_id=dstringt::make_from_table_index( \
static_cast<unsigned>(idt::id_##the_id));
#define IREP_ID_TWO(the_id, str) \
const dstringt ID_##the_id=dstringt::make_from_table_index( \
static_cast<unsigned>(idt::id_##the_id));

#else

#define IREP_ID_ONE(the_id) const std::string ID_##the_id(#the_id);
#define IREP_ID_TWO(the_id, str) const std::string ID_##the_id(#the_id);

#endif

#include "irep_ids.def" // NOLINT(build/include)

#endif

string_containert::string_containert()
{
// pre-allocate empty string -- this gets index 0
Expand Down
111 changes: 109 additions & 2 deletions src/util/irep_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,115 @@ Author: Reuben Thomas, [email protected]

#ifdef USE_DSTRING

#define IREP_ID_ONE(the_id) extern const dstringt ID_##the_id;
#define IREP_ID_TWO(the_id, str) extern const dstringt ID_##the_id;
enum class idt : unsigned
{
#define IREP_ID_ONE(the_id) id_##the_id,
#define IREP_ID_TWO(the_id, str) id_##the_id,

#include "irep_ids.def" // NOLINT(build/include)
};

class irep_idt final : public dstringt
{
public:
// this is safe for static objects
#ifdef __GNUC__
constexpr
#endif
irep_idt()
: dstringt()
{
}

// this is safe for static objects
#ifdef __GNUC__
constexpr
#endif
static irep_idt
make_from_table_index(unsigned no)
{
return irep_idt(no);
}

#ifdef __GNUC__
// This conversion allows the use of irep_idts
// in switch ... case statements.
constexpr operator idt() const
{
return static_cast<idt>(no);
}
#endif

// this one is safe for static objects
#ifdef __GNUC__
constexpr
#endif
// NOLINTNEXTLINE(runtime/explicit)
irep_idt(dstringt s)
: dstringt(s)
{
}

// this one is not safe for static objects
// NOLINTNEXTLINE(runtime/explicit)
irep_idt(const char *s) : dstringt(s)
{
}

// this one is not safe for static objects
// NOLINTNEXTLINE(runtime/explicit)
irep_idt(const std::string &s) : dstringt(s)
{
}

protected:
#ifdef __GNUC__
constexpr
#endif
explicit irep_idt(unsigned _no)
: dstringt(_no)
{
}
};

// NOLINTNEXTLINE [allow specialisation within 'std']
namespace std
{
/// Default hash function of `dstringt` for use with STL containers.
template <>
struct hash<irep_idt> // NOLINT(readability/identifiers)
{
size_t operator()(const irep_idt &irep_id) const
{
return irep_id.hash();
}
};
} // namespace std

#ifdef __GNUC__
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clang, MSVC 2015+ also have this. Suggest stealing the testing logic used at https://github.com/diffblue/cbmc/blob/develop/src/nonstd/optional.hpp#L87

#define IREP_ID_ONE(the_id) \
constexpr irep_idt ID_##the_id = \
irep_idt::make_from_table_index(static_cast<unsigned>(idt::id_##the_id));
#define IREP_ID_TWO(the_id, str) \
constexpr irep_idt ID_##the_id = \
irep_idt::make_from_table_index(static_cast<unsigned>(idt::id_##the_id));
#else
#define IREP_ID_ONE(the_id) \
const irep_idt ID_##the_id = \
irep_idt::make_from_table_index(static_cast<unsigned>(idt::id_##the_id));
#define IREP_ID_TWO(the_id, str) \
const const irep_idt ID_##the_id = \
irep_idt::make_from_table_index(static_cast<unsigned>(idt::id_##the_id));
#endif

template <>
struct diagnostics_helpert<irep_idt>
{
static std::string diagnostics_as_string(const irep_idt &irep_id)
{
return as_string(irep_id);
}
};

#else

Expand Down