// Project Identifier: C0F4DFE8B340D81183C208F70F9D2D797908754D // EECS 281 Project 3 SillyQL TableEntry class // Copyright 2020, Regents of the University of Michigan #pragma once #include #include #include #include #include // The type contained within a TableEntry; you can use this also. enum class EntryType : uint8_t { String, Double, Int, Bool }; class TableEntry { public: /* TableEntry can be constructed out of a string, an int, a double, or a bool. * Don't worry about the string&& constructor. This is a C++11 move * constructor. Understanding how these work is not required for this project. */ explicit TableEntry(const char*); explicit TableEntry(const std::string&); explicit TableEntry(std::string&&); explicit TableEntry(double); explicit TableEntry(int); explicit TableEntry(bool); // You can also copy construct a TableEntry. Don't worry about TableEntry&& TableEntry(const TableEntry&); TableEntry(TableEntry&&) noexcept; // Please don't be assigning TableEntry& operator=(const TableEntry&) = delete; TableEntry& operator=(TableEntry&&) = delete; // IAMA destructor AMA ~TableEntry() noexcept; /* Comparisons with other TableEntry. * Don't try to compare TableEntry containing different types. * If you don't pass -DNDEBUG to g++ the compilation process (make debug with * the provided Makefile doesn't do this, but make release does), this will * cause an assertion to fail, which you can debug by using gdb (or your * favorite visual debugger) and looking at the stacktrace. Asserts are * removed if you compile with -DNDEBUG, and comparing different types causes * undefined behavior, which makes the autograder cry. */ bool operator<(const TableEntry&) const noexcept; bool operator>(const TableEntry&) const noexcept; bool operator==(const TableEntry&) const noexcept; bool operator!=(const TableEntry&) const noexcept; /* Comparisons against internal type for convenience. These allow you to use * TableEntry as if they were the actul types stored in them. If you try to * compare a TableEntry with a type that is not the same as the internal type, * an assertion will trigger in the same way as for the above comparisons * * If you try to compare against a type other than the ones representable by * TableEntry, you will get a compiler error. That's what this gigantic * template/using is for. Don't worry about how it works. */ template // When c++14 becomes more used, change to decay_t and enable_if_t using Only_allow_for_table_types_t = typename std::enable_if< std::is_same::type, double>::value || std::is_same::type, int>::value || std::is_same::type, bool>::value || std::is_same::type, std::string>::value>::type; template > bool operator<(const T&) const noexcept; template > bool operator>(const T&) const noexcept; template > bool operator==(const T&) const noexcept; template > bool operator!=(const T&) const noexcept; private: // Stop looking at my privates. You won't like what you see. // Skip down to after the end of the class for some other things EntryType tag; union { std::string data_string; double data_double; int data_int; bool data_bool; }; friend struct std::hash; friend std::ostream& operator<<(std::ostream&, const TableEntry&); /* fast_pass taken from facebook's fatal library. written by Marcelo Juchem https://github.com/facebook/fatal/blob/master/fatal/type/fast_pass.h Modified slightly to apply here change to decay_t, add_const_t, condtional_t, and bool_constant as they become available. tl/dr if it's a scalar type, pass in as is, otherwise use a const& */ template using is_fast_pass = std::integral_constant< bool, std::is_scalar::type>::value>; template using fast_pass = typename std::conditional< is_fast_pass::type>::value, typename std::decay::type, typename std::add_lvalue_reference::type>::type>::type>::type; // as operator to use the TableEntry as if it were type T. Only implemented // for the types allowed as TableEntry and returns a const& for string. template fast_pass as() const noexcept; // helper for comparisons with other TableEntry. // Change to template