mirror of
https://github.com/ksherlock/wdc-utils.git
synced 2025-01-20 14:31:28 +00:00
add c++17 optional
This commit is contained in:
parent
eb993acd2a
commit
1deafa3ad1
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
||||
LINK.o = $(LINK.cc)
|
||||
CXXFLAGS = -std=c++11 -g -Wall
|
||||
CXXFLAGS = -std=c++14 -g -Wall
|
||||
CCFLAGS = -g
|
||||
|
||||
DUMP_OBJS = dumpobj.o disassembler.o zrdz_disassembler.o
|
||||
|
@ -145,9 +145,7 @@ bool simplify_expression(expression &e) {
|
||||
* if force is true, treat OP_LOC records as OP_VAL (for omf)
|
||||
*/
|
||||
|
||||
// should return std::optional<uint32_t>...
|
||||
|
||||
uint32_t evaluate_expression(expression &e, bool force) {
|
||||
optional<uint32_t> evaluate_expression(expression &e, bool force) {
|
||||
std::vector<expr> tmp;
|
||||
for (const auto &t : e.stack) {
|
||||
if (t.tag == OP_LOC && force) {
|
||||
@ -163,7 +161,7 @@ uint32_t evaluate_expression(expression &e, bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp.size() == 1 && tmp.front().tag == OP_VAL) return tmp.front().value;
|
||||
return 0;
|
||||
if (tmp.size() == 1 && tmp.front().tag == OP_VAL) return optional<uint32_t>(tmp.front().value);
|
||||
return optional<uint32_t>();
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include "optional.h"
|
||||
|
||||
struct expr {
|
||||
expr(int t = 0, uint32_t v = 0, uint32_t s = 0)
|
||||
: tag(t), value(v), section(s)
|
||||
@ -25,7 +27,7 @@ struct expression {
|
||||
|
||||
};
|
||||
|
||||
uint32_t evaluate_expression(expression &e, bool force = false);
|
||||
optional<uint32_t> evaluate_expression(expression &e, bool force = false);
|
||||
|
||||
bool simplify_expression(expression &e);
|
||||
|
||||
|
139
optional.h
Normal file
139
optional.h
Normal file
@ -0,0 +1,139 @@
|
||||
#ifndef __optional_h__
|
||||
#define __optional_h__
|
||||
|
||||
#include <type_traits>
|
||||
#include <stdexcept>
|
||||
|
||||
class bad_optional_access : public std::exception {
|
||||
public:
|
||||
virtual const char* what() const noexcept {
|
||||
return "bad optional access";
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class optional {
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
optional() = default;
|
||||
|
||||
optional( const optional& other ) {
|
||||
if (other._engaged) {
|
||||
new (std::addressof(_data)) T(*other);
|
||||
_engaged = true;
|
||||
}
|
||||
}
|
||||
|
||||
optional( const optional&& other ) {
|
||||
if (other._engaged) {
|
||||
new (std::addressof(_data)) T(std::move(*other));
|
||||
_engaged = true;
|
||||
}
|
||||
}
|
||||
|
||||
template < class U >
|
||||
optional( const optional<U>& other ) {
|
||||
if (other._engaged) {
|
||||
new (std::addressof(_data)) T(*other);
|
||||
_engaged = true;
|
||||
}
|
||||
}
|
||||
|
||||
template < class U >
|
||||
optional( optional<U>&& other ) {
|
||||
if (other._engaged) {
|
||||
new (std::addressof(_data)) T(std::move(*other));
|
||||
_engaged = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class U = T>
|
||||
optional(U &&value) {
|
||||
new(std::addressof(_data)) T(std::forward<U>(value));
|
||||
_engaged = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
~optional() {
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
constexpr explicit operator bool() const {
|
||||
return _engaged;
|
||||
}
|
||||
|
||||
constexpr bool has_value() const {
|
||||
return _engaged;
|
||||
}
|
||||
|
||||
/* these should throw ... */
|
||||
constexpr T& value() & {
|
||||
if (!_engaged) throw bad_optional_access();
|
||||
return *reinterpret_cast<T*>(std::addressof(_data));
|
||||
}
|
||||
|
||||
constexpr const T & value() const & {
|
||||
if (!_engaged) throw bad_optional_access();
|
||||
return *reinterpret_cast<const T*>(std::addressof(_data));
|
||||
}
|
||||
|
||||
constexpr T&& value() && {
|
||||
if (!_engaged) throw bad_optional_access();
|
||||
return *reinterpret_cast<T*>(std::addressof(_data));
|
||||
}
|
||||
|
||||
constexpr const T&& value() const && {
|
||||
if (!_engaged) throw bad_optional_access();
|
||||
return *reinterpret_cast<const T*>(std::addressof(_data));
|
||||
}
|
||||
|
||||
|
||||
template< class U >
|
||||
constexpr T value_or( U&& default_value ) const& {
|
||||
return bool(*this) ? **this : static_cast<T>(std::forward<U>(default_value));
|
||||
}
|
||||
|
||||
template< class U >
|
||||
constexpr T value_or( U&& default_value ) && {
|
||||
return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(default_value));
|
||||
}
|
||||
|
||||
constexpr const T* operator->() const {
|
||||
return reinterpret_cast<const T*>(std::addressof(_data));
|
||||
}
|
||||
constexpr T* operator->() {
|
||||
return reinterpret_cast<T*>(std::addressof(_data));
|
||||
}
|
||||
|
||||
constexpr const T& operator*() const& {
|
||||
return *reinterpret_cast<const T*>(std::addressof(_data));
|
||||
}
|
||||
constexpr T& operator*() & {
|
||||
return *reinterpret_cast<T*>(std::addressof(_data));
|
||||
}
|
||||
constexpr const T&& operator*() const&& {
|
||||
return *reinterpret_cast<const T*>(std::addressof(_data));
|
||||
}
|
||||
constexpr T&& operator*() && {
|
||||
return *reinterpret_cast<T*>(std::addressof(_data));
|
||||
}
|
||||
|
||||
|
||||
void reset() {
|
||||
if (_engaged) {
|
||||
reinterpret_cast<const T*>(std::addressof(_data))->~T();
|
||||
_engaged = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool _engaged = false;
|
||||
typename std::aligned_storage<sizeof(T), alignof(T)>::type _data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user