Files
Giacomo Vercesi 704c5e9bbb TupleTree: fix broken operator==
The `operator==` for keyed `StructDefinitions` was the comparison
between keys, which is misleading.
2026-03-04 14:58:02 +01:00

354 lines
11 KiB
Smarty

#pragma once
/*#-
This template file is distributed under the MIT License. See LICENSE.md for details.
The notice below applies to the generated files.
#*/
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
// This file is autogenerated! Do not edit it directly
#include <compare>
#include "revng/ADT/TrackingContainer.h"
#include "revng/TupleTree/TupleTreeDiff.h"
#include "revng/TupleTree/TupleTreeReference.h"
#include "revng/Support/Assert.h"
/**- if emit_tracking **/
#include "revng/Support/AccessTracker.h"
/**- endif **/
void fieldAccessed(llvm::StringRef FieldName, llvm::StringRef StructName);
/** for header in includes **/
#include "/*= user_include_path =*//*= header =*/"
/**- endfor **/
/** if emit_tracking **/
namespace revng {
struct TrackingImpl;
}
struct ReadFields;
/**- endif **/
/*= struct.doc | docstring -=*/
struct /*= struct | fullname =*/
/**- if struct.inherits **/ : public /*= struct.inherits | user_fullname =*/ /** endif -**/
{
friend struct revng::TrackingImpl;
/** if emit_tracking -**/
inline static constexpr bool HasTracking = true;
/**- else **/
inline static constexpr bool HasTracking = false;
/**- endif **/
/** if struct.inherits **/
static constexpr const /*= struct.inherits.name =*/Kind::Values AssociatedKind = /*= struct.inherits.name =*/Kind::/*= struct.name =*/;
using BaseClass = /*= struct.inherits | user_fullname =*/;
/**- else **//** if struct.abstract **/
static constexpr const /*= struct.name =*/Kind::Values AssociatedKind = /*= struct.name =*/Kind::Invalid;
using BaseClass = /*= struct | user_fullname =*/;
/**- else **/
using BaseClass = void;
/**- endif **//** endif **/
private:
//
// Member list
//
/**- for field in struct.fields **/
/*= field | field_type =*/ The/*= field.name =*/ = /*= field | get_default_value =*/;
/**- endfor **/
/** for field in struct.fields **/
static_assert(Yamlizable</*= field | field_type =*/>);
/**- endfor **/
/** if emit_tracking -**/
//
// Tracking helpers
//
/**- for field in struct.fields **/
mutable revng::AccessTracker /*= field.name =*/Tracker = revng::AccessTracker(false);
/**- endfor **/
/**- endif **/
/**- if struct.name == root_type **/
public:
static constexpr uint64_t SchemaVersion = /*=version=*/;
/**- endif **/
public:
//
// Member accessors
//
/**- for field in struct.fields **/
/*= field.doc | docstring -=*/
const /*= field | field_type =*/ & /*= field.name =*/() const {
/**- if emit_tracking **/
/**- if not field in struct.key_fields **/
/**- if field.resolved_type.is_scalar **/
#ifdef TUPLE_TREE_GENERATOR_EMIT_TRACKING_DEBUG
fieldAccessed("/*= field.name =*/" , "/*= struct | fullname =*/");
#endif
/*= field.name =*/Tracker.access();
/** endif -**/
/** endif -**/
/** endif -**/
return The/*= field.name =*/;
}
/**- endfor **/
/**- for field in struct.fields **/
/*= field.doc | docstring -=*/
/*= field | field_type =*/ & /*= field.name =*/() {
return The/*= field.name =*/;
}
/**- endfor **/
/** for field in struct.fields **/
using TypeOf/*= field.name =*/ = /*= field | field_type =*/;
/**- endfor **/
/// Default constructor
/*= struct.name =*/() :
/**- if struct.inherits **//*= struct.inherits.name =*/()/** endif **/
/**- for field in struct.fields **/
/**- if not loop.first or struct.inherits **/, /** endif **/The/*= field.name =*/(
/**- if struct.name == root_type and field.name == "Version" -**/
SchemaVersion
/**- else -**/
/*= field | get_default_value =*/
/**- endif -**/
)
/**- endfor **/ {
/**- if struct.inherits -**/
Kind() = AssociatedKind;
/**- endif -**/
}
/** if struct.abstract **/
protected:
/// Copy and move constructors
/*= struct.name =*/(const /*= struct.name =*/ &Another) = default;
/*= struct.name =*/(/*= struct.name =*/ &&Another) = default;
/*= struct.name =*/ &operator=(const /*= struct.name =*/ &Another) = default;
/*= struct.name =*/ &operator=(/*= struct.name =*/ &&Another) = default;
public:
/** else **/
/// Copy and move constructors
/*= struct.name =*/(const /*= struct.name =*/ &Another) = default;
/*= struct.name =*/(/*= struct.name =*/ &&Another) = default;
/*= struct.name =*/ &operator=(const /*= struct.name =*/ &Another) = default;
/*= struct.name =*/ &operator=(/*= struct.name =*/ &&Another) = default;
/** endif **/
/**- if struct.key_fields **/
/// Key constructor
/*= struct.name =*/(
/**- for field in struct.key_fields **/
/*=- field | field_type =*/ /*= field.name =*//** if not loop.last **/, /** endif **/
/**- endfor **/
) :
/**- if struct.inherits **/
/*=- struct.inherits.name =*/(
/**- for field in struct.key_fields **/
/*=- field.name =*//** if not loop.last **/, /** endif **/
/**- endfor **/
)
/**- else **/
/**- for field in struct.key_fields **/
The/*=- field.name =*/(/*= field.name =*/)/** if not loop.last **/, /** endif **/
/**- endfor **/
/**- endif **/ {
/**- if struct.inherits and not 'Kind' in struct.key_fields | map(attribute='name') -**/
Kind() = AssociatedKind;
/**- endif -**/
}
/** endif **/
/** if struct.emit_full_constructor **/
/// Full constructor
/*= struct.name =*/(
/*#- Inherited fields #*/
/**- for field in struct.inherits.fields **/
/**- if field.name != 'Kind' **/
/*=- field | field_type =*/ /*= field.name =*/
/** if (struct.fields | length > 0) or (not loop.last) **/, /** endif **/
/**- endif **/
/**- endfor **/
/*#- Own fields #*/
/*#- Generate for all fields except the implicitly-defined "Version" field of the root type. -#*/
/**- for field in (struct.fields if struct.name != root_type else struct.fields | rejectattr("name", "equalto", "Version")) | list **/
/*=- field | field_type =*/ /*= field.name =*/
/**- if not loop.last **/, /** endif -**/
/**- endfor **/
) :
/*#- Invoke base class constructor #*/
/**- if struct.inherits **/
/*= struct.inherits.name =*/(
/**- for field in struct.inherits.fields **/
/**- if field.name != 'Kind' **/
/*=- field.name =*/
/**- if not loop.last **/, /** endif -**/
/**- else **/
AssociatedKind
/**- if not loop.last **/, /** endif -**/
/**- endif **/
/**- endfor **/
)
/** if struct.fields | length > 0 **/, /** endif **/
/**- endif **/
/*#- Initialize own fields #*/
/**- for field in struct.fields **/
The/*=- field.name =*/(
/**- if struct.name == root_type and field.name == "Version" -**/
SchemaVersion
/**- else -**/
/*= field.name =*/
/**- endif -**/
) /** if not loop.last **/, /** endif **/
/**- endfor **/ {}
/** endif **/
/** if struct._key **/
// Key definition for KeyedObjectTraits
using KeyTuple = std::tuple<
/**- for key_field in struct.key_fields -**/
/*= key_field | field_type =*//** if not loop.last **/, /** endif **/
/**- endfor -**/
>;
struct Key : public KeyTuple {
static constexpr bool LastFieldIsKind = true;
using KeyTuple::KeyTuple;
};
/** endif **/
// Comparison operators
/** if not struct.inherits **/
/** if struct.key_fields -**/
Key key() const {
return Key {
/**- for key_field in struct.key_fields -**/
/*= key_field.name =*/()/** if not loop.last **/, /** endif **/
/**- endfor -**/
};
}
bool operator<(const /*= struct.name =*/ &Other) const { return key() < Other.key(); }
bool operator>(const /*= struct.name =*/ &Other) const { return key() > Other.key(); }
/** endif **/
/** endif **/
bool operator==(const /*= struct.name =*/ &Other) const {
/**- for field in struct.all_fields **/
if (/*= field.name =*/() != Other./*= field.name =*/())
return false;
/**- endfor **/
return true;
}
/**- if emit_tracking **/
private:
// Tracking helpers
template<size_t I>
revng::AccessTracker& getTracker() const {
/**- for field in struct.all_fields **/
if constexpr (I == /*= loop.index0 =*/)
return /*= field.name =*/Tracker;
/**- endfor -**/
}
/** if upcastable **/
/**- for child_type in upcastable|sort(attribute="user_fullname") **/
friend /*= child_type | fullname =*/;
/**- endfor **/
/** endif **/
template<size_t I>
const auto& untrackedGet() const {
if constexpr (false)
return 0;
/**- for field in struct.all_fields **/
else if constexpr (I == /*= loop.index0 =*/)
return The/*= field.name =*/;
/**- endfor -**/
}
/** if struct._key **/
Key untrackedKey() const {
return {
/** for key_field in struct.key_fields -**/
The/*= key_field.name =*/
/**- if not loop.last **/,
/** endif **/
/**- endfor **/
};
}
/** endif **/
/** endif -**/
public:
bool localCompare(const /*= struct | user_fullname =*/ &Other) const;
void dump(llvm::raw_ostream &Stream) const;
void dump(std::ostream &Stream) const {
llvm::raw_os_ostream LLVMStreamAdapter(Stream);
dump(LLVMStreamAdapter);
}
void dump() const debug_function { dump(dbg); }
void dump(const char *Path) const debug_function;
std::string toString() const debug_function;
/**- if struct.abstract **/
public:
static bool classof(const /*= struct | user_fullname =*/ *P) { return true; }
/** endif **/
/**- if struct.inherits **/
public:
static bool classof(const /*= struct.inherits | user_fullname =*/ *P);
static bool classof(const /*= struct.inherits.name =*/Kind::Values &Kind) { return Kind == AssociatedKind; }
/** endif -**/
};
/** if struct._key **/
template<>
struct std::tuple_size</*= struct | fullname =*/::Key>
: public std::tuple_size</*= struct | fullname =*/::KeyTuple> {};
template<size_t I>
struct std::tuple_element<I, /*= struct | fullname =*/::Key>
: public std::tuple_element<I, /*= struct | fullname =*/::KeyTuple> {};
template<>
struct std::hash<const /*= struct | fullname =*/::Key> {
size_t operator()(const /*= struct | fullname =*/::Key &Key) const {
return llvm::hash_value(Key);
}
};
template<>
struct std::hash</*= struct | fullname =*/::Key> : std::hash<const /*= struct | fullname =*/::Key> {};
/** endif **/
/*# --- UpcastablePointer stuff --- #*/
/** if upcastable **/
/*# Emit both const and non-const specialization of concrete_types_traits #*/
/** for const_qualifier in ["", "const"] **/
template<>
struct concrete_types_traits</*= const_qualifier =*/ /*= struct | user_fullname =*/> {
using type = std::tuple<
/**- for child_type in upcastable|sort(attribute="user_fullname") **/
/*=- const_qualifier =*/ /*= child_type | user_fullname =*//** if not loop.last **/, /** endif **/
/**- endfor **/
/**- if not struct.abstract **/, /*=- const_qualifier =*/ /*= struct | user_fullname =*//** endif **/>;
};
/** endfor **/
/** endif **//*# End UpcastablePointer stuff #*/