memgraph/include/storage/model/properties/flags.hpp

152 lines
4.4 KiB
C++

#pragma once
#include <cassert>
#include <ostream>
#include <string>
#include <vector>
#include "utils/total_ordering.hpp"
#include "utils/underlying_cast.hpp"
// TODO: Revise this
// NOTE: Why not just count all the types?
enum class Flags : unsigned
{
// Type | Mask
// -----------+----------------------------------------
// Null | 0000 0000 0000 0000 0000 0000 0000 0000
// -----------+----------------------------------------
// Bool | 0000 0000 0000 0000 0000 0000 0000 0001
// + True | 0000 0000 0000 0000 0000 0000 0000 0011
// + False | 0000 0000 0000 0000 0000 0000 0000 0101
// -----------+----------------------------------------
// String | 0000 0000 0000 0000 0000 0000 0000 1000
// -----------+----------------------------------------
// Number | 0000 0000 0000 0000 0000 0000 0001 0000
// + Integral | 0000 0000 0000 0000 0000 0000 0011 0000
// + Int32 | 0000 0000 0000 0000 0000 0000 0111 0000
// + Int64 | 0000 0000 0000 0000 0000 0000 1011 0000
// + Floating | 0000 0000 0000 0000 0000 0001 0001 0000
// + Float | 0000 0000 0000 0000 0000 0011 0001 0000
// + Double | 0000 0000 0000 0000 0000 0101 0001 0000
// -----------+----------------------------------------
// Array | 0000 0000 0000 0000 0001 0000 0000 0000
// -----------+----------------------------------------
Null = 0x0,
Bool = 0x1,
// TODO remove this two values
True = 0x2 | Bool,
False = 0x4 | Bool,
String = 0x8,
Number = 0x10,
Integral = 0x20 | Number,
Int32 = 0x40 | Integral,
Int64 = 0x80 | Integral,
Floating = 0x100 | Number,
Float = 0x200 | Floating,
Double = 0x400 | Floating,
Array = 0x1000,
ArrayBool = (Bool << 13) | Array,
ArrayString = (String << 13) | Array,
ArrayInt32 = (Int32 << 13) | Array,
ArrayInt64 = (Int64 << 13) | Array,
ArrayFloat = (Float << 13) | Array,
ArrayDouble = (Double << 13) | Array,
type_mask = 0xFFFFFF
};
// Mask to turn flags into type. It passes all bits except 0x2 and 0x4 which
// correspond
// to True and False.
const unsigned flags_equal_mask = 0xFF3FF9;
class Type : public TotalOrdering<Type>
{
public:
constexpr Type(Flags f) : value(underlying_cast(f) & flags_equal_mask)
{
Flags o = Flags(value);
assert(o == Flags::Null || o == Flags::Bool || o == Flags::String ||
o == Flags::Int32 || o == Flags::Int64 || o == Flags::Float ||
o == Flags::Double || o == Flags::ArrayBool ||
o == Flags::ArrayString || o == Flags::ArrayInt32 ||
o == Flags::ArrayInt64 || o == Flags::ArrayFloat ||
o == Flags::ArrayDouble);
}
const std::string to_str() const
{
switch (flags()) {
case Flags::Null:
return "null";
case Flags::Bool:
return "bool";
case Flags::String:
return "str";
case Flags::Int32:
return "int32";
case Flags::Int64:
return "int64";
case Flags::Float:
return "float";
case Flags::Double:
return "double";
case Flags::ArrayBool:
return "array_bool";
case Flags::ArrayString:
return "array_string";
case Flags::ArrayInt64:
return "array_int64";
case Flags::ArrayInt32:
return "array_int32";
case Flags::ArrayFloat:
return "array_float";
case Flags::ArrayDouble:
return "array_double";
default:
assert(false);
return "err_unknown_type_" + std::to_string(value);
}
}
Flags flags() const { return Flags(value); }
Type get_type() const { return *this; }
bool is_array() const
{
return (value & underlying_cast(Flags::Array)) != 0;
}
template <class T>
bool is() const
{
return *this == T::type;
}
bool operator==(Flags other) const { return *this == Type(other); }
bool operator!=(Flags other) const { return *this != Type(other); }
friend bool operator<(const Type &lhs, const Type &rhs)
{
return lhs.value < rhs.value;
}
friend bool operator==(const Type &lhs, const Type &rhs)
{
return lhs.value == rhs.value;
}
private:
const unsigned value; // TODO: turn this to flags
};