Skip to content

Commit

Permalink
Optional<T> formatt
Browse files Browse the repository at this point in the history
  • Loading branch information
mozga-intel committed Aug 27, 2021
1 parent ecd30bf commit 29211ba
Showing 1 changed file with 81 additions and 81 deletions.
162 changes: 81 additions & 81 deletions include/dmlc/optional.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
#ifndef DMLC_OPTIONAL_H_
#define DMLC_OPTIONAL_H_

#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <algorithm>

#include "./base.h"
#include "./common.h"
Expand All @@ -33,7 +33,8 @@ struct nullopt_t {
constexpr const nullopt_t nullopt = nullopt_t(0);
/*! C++14 aliases */
template <typename T> using decay_t = typename std::decay<T>::type;
template <bool B, typename T = void> using enable_if_t = typename std::enable_if<B, T>::type;
template <bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;

struct in_place_t {
explicit in_place_t() = default;
Expand All @@ -47,9 +48,8 @@ static constexpr in_place_t in_place{};
* hold no value (string representation "None")
* or hold a value of type T.
*/
template<typename T>
class optional {
public:
template <typename T> class optional {
public:
/*! \brief construct an optional object that contains no value */
optional() : is_none(true) {}

Expand All @@ -58,32 +58,31 @@ class optional {
optional(const optional &other) = default;

optional(optional &&other) = default;


template <typename U = T,
enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr,
enable_if_t<
std::is_convertible<T, U &&>::value &&
!std::is_same<decay_t<U>, in_place_t>::value &&
!std::is_same<optional<T>, decay_t<U>>::value> * = nullptr>
optional(U &&other) noexcept {
new (&val) T(std::forward<U>(other));
is_none = false;

template <
typename U = T,
enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr,
enable_if_t<std::is_convertible<T, U &&>::value &&
!std::is_same<decay_t<U>, in_place_t>::value &&
!std::is_same<optional<T>, decay_t<U>>::value> * = nullptr>
optional(U &&other) noexcept {
new (&val) T(std::forward<U>(other));
is_none = false;
}

template <typename U = T,
enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr,
enable_if_t<
std::is_convertible<T, U &&>::value &&
!std::is_same<decay_t<U>, in_place_t>::value &&
!std::is_same<optional<T>, decay_t<U>>::value> * = nullptr>
explicit optional(U &&other) noexcept {
new (&val) T(std::forward<U>(other));
is_none = false;
template <
typename U = T,
enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr,
enable_if_t<std::is_convertible<T, U &&>::value &&
!std::is_same<decay_t<U>, in_place_t>::value &&
!std::is_same<optional<T>, decay_t<U>>::value> * = nullptr>
explicit optional(U &&other) noexcept {
new (&val) T(std::forward<U>(other));
is_none = false;
}

template <
typename U,
typename U,
enable_if_t<std::is_constructible<T, const U &>::value &&
!std::is_constructible<T, optional<U> &>::value &&
!std::is_constructible<T, optional<U> &&>::value &&
Expand All @@ -92,75 +91,78 @@ class optional {
!std::is_convertible<optional<U> &, T>::value &&
!std::is_convertible<optional<U> &&, T>::value &&
!std::is_convertible<const optional<U> &, T>::value &&
!std::is_convertible<const optional<U> &&, T>::value> * = nullptr,
!std::is_convertible<const optional<U> &&, T>::value> * =
nullptr,
enable_if_t<std::is_convertible<const U &, T>::value> * = nullptr>
optional(const optional<U> &other) {
if(other.has_value()) {
new (&val) T(std::forward<U>(other));
is_none = false;
}
}
if (other.has_value()) {
new (&val) T(std::forward<U>(other));
is_none = false;
}
}

template <
typename U,
enable_if_t<std::is_constructible<T, const U &>::value &&
typename U,
enable_if_t<std::is_constructible<T, const U &>::value &&
!std::is_constructible<T, optional<U> &>::value &&
!std::is_constructible<T, optional<U> &&>::value &&
!std::is_constructible<T, const optional<U> &>::value &&
!std::is_constructible<T, const optional<U> &&>::value &&
!std::is_convertible<optional<U> &, T>::value &&
!std::is_convertible<optional<U> &&, T>::value &&
!std::is_convertible<const optional<U> &, T>::value &&
!std::is_convertible<const optional<U> &&, T>::value> * = nullptr,
enable_if_t<!std::is_convertible<const U &&, T>::value> * = nullptr>
!std::is_convertible<const optional<U> &&, T>::value> * =
nullptr,
enable_if_t<!std::is_convertible<const U &&, T>::value> * = nullptr>
explicit optional(const optional<U> &other) {
if(other.has_value()) {
new (&val) T(std::forward<U>(other));
is_none = false;
}
}

if (other.has_value()) {
new (&val) T(std::forward<U>(other));
is_none = false;
}
}

/*! \brief converting move constructor. */
template <
typename U,
enable_if_t<std::is_constructible<T, U &&>::value &&
typename U,
enable_if_t<std::is_constructible<T, U &&>::value &&
!std::is_constructible<T, optional<U> &>::value &&
!std::is_constructible<T, optional<U> &&>::value &&
!std::is_constructible<T, const optional<U> &>::value &&
!std::is_constructible<T, const optional<U> &&>::value &&
!std::is_convertible<optional<U> &, T>::value &&
!std::is_convertible<optional<U> &&, T>::value &&
!std::is_convertible<const optional<U> &, T>::value &&
!std::is_convertible<const optional<U> &&, T>::value> * = nullptr,
enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr>
!std::is_convertible<const optional<U> &&, T>::value> * =
nullptr,
enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr>
optional(optional<U> &&other) {
if(other.has_value()) {
if (other.has_value()) {
new (&val) T(std::forward<U>(other));
is_none = false;
}
}
}

/*! \brief explicit converting move constructor. */
template <
typename U,
enable_if_t<std::is_constructible<T, U &&>::value &&
typename U,
enable_if_t<std::is_constructible<T, U &&>::value &&
!std::is_constructible<T, optional<U> &>::value &&
!std::is_constructible<T, optional<U> &&>::value &&
!std::is_constructible<T, const optional<U> &>::value &&
!std::is_constructible<T, const optional<U> &&>::value &&
!std::is_convertible<optional<U> &, T>::value &&
!std::is_convertible<optional<U> &&, T>::value &&
!std::is_convertible<const optional<U> &, T>::value &&
!std::is_convertible<const optional<U> &&, T>::value> * = nullptr,
enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr>
explicit optional(optional<U> &&other) {
if(other.has_value()) {
!std::is_convertible<const optional<U> &&, T>::value> * =
nullptr,
enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr>
explicit optional(optional<U> &&other) {
if (other.has_value()) {
new (&val) T(std::forward<U>(other));
is_none = false;
}
}

/*! \brief reset */
void reset() noexcept {
if (!is_none)
Expand All @@ -171,65 +173,63 @@ class optional {
/*! \brief deconstructor */
~optional() {
if (!is_none) {
reinterpret_cast<T*>(&val)->~T();
reinterpret_cast<T *>(&val)->~T();
}
}
/*! \brief swap two optional */
void swap(optional<T>& other) {
void swap(optional<T> &other) {
std::swap(val, other.val);
std::swap(is_none, other.is_none);
}
/*! \brief set this object to hold value
* \param value the value to hold
* \return return self to support chain assignment
*/
optional<T>& operator=(const T& value) {
optional<T> &operator=(const T &value) {
(optional<T>(value)).swap(*this);
return *this;
}
/*! \brief set this object to hold the same value with other
* \param other the other object
* \return return self to support chain assignment
*/
optional<T>& operator=(const optional<T> &other) {
optional<T> &operator=(const optional<T> &other) {
(optional<T>(other)).swap(*this);
return *this;
}
/*! \brief clear the value this object is holding.
* optional<T> x = nullopt;
*/
optional<T>& operator=(nullopt_t) {
optional<T> &operator=(nullopt_t) {
(optional<T>()).swap(*this);
return *this;
}
/*! \brief non-const dereference operator */
T& operator*() { // NOLINT(*)
return *reinterpret_cast<T*>(&val);
T &operator*() { // NOLINT(*)
return *reinterpret_cast<T *>(&val);
}
/*! \brief const dereference operator */
const T& operator*() const {
return *reinterpret_cast<const T*>(&val);
}
const T &operator*() const { return *reinterpret_cast<const T *>(&val); }
/*! \brief equal comparison */
bool operator==(const optional<T>& other) const {
bool operator==(const optional<T> &other) const {
return this->is_none == other.is_none &&
(this->is_none == true || this->value() == other.value());
}
/*! \brief return the holded value.
* throws std::logic_error if holding no value
*/
const T& value() const {
const T &value() const {
if (is_none) {
throw std::logic_error("bad optional access");
}
return *reinterpret_cast<const T*>(&val);
return *reinterpret_cast<const T *>(&val);
}
/*! \brief whether this object is holding a value */
explicit operator bool() const { return !is_none; }
/*! \brief whether this object is holding a value (alternate form). */
bool has_value() const { return operator bool(); }

private:
private:
// whether this is none
bool is_none;
// on stack storage of value
Expand All @@ -249,7 +249,7 @@ class optional {
* \param t source optional<T> object
* \return output stream
*/
template<typename T>
template <typename T>
std::ostream &operator<<(std::ostream &os, const optional<T> &t) {
if (t) {
os << *t;
Expand All @@ -276,19 +276,20 @@ std::ostream &operator<<(std::ostream &os, const optional<T> &t) {
* \param t target optional<T> object
* \return input stream
*/
template<typename T>
template <typename T>
std::istream &operator>>(std::istream &is, optional<T> &t) {
char buf[4];
std::streampos origin = is.tellg();
is.read(buf, 4);
if (is.fail() || buf[0] != 'N' || buf[1] != 'o' ||
buf[2] != 'n' || buf[3] != 'e') {
if (is.fail() || buf[0] != 'N' || buf[1] != 'o' || buf[2] != 'n' ||
buf[3] != 'e') {
is.clear();
is.seekg(origin);
T x;
is >> x;
t = x;
if (std::is_integral<T>::value && !is.eof() && is.peek() == 'L') is.get();
if (std::is_integral<T>::value && !is.eof() && is.peek() == 'L')
is.get();
} else {
t = nullopt;
}
Expand Down Expand Up @@ -348,18 +349,17 @@ DMLC_DECLARE_TYPE_NAME(optional<float>, "float or None");
/*! \brief description for optional double */
DMLC_DECLARE_TYPE_NAME(optional<double>, "double or None");

} // namespace dmlc
} // namespace dmlc

namespace std {
/*! \brief std hash function for optional */
template<typename T>
struct hash<dmlc::optional<T> > {
template <typename T> struct hash<dmlc::optional<T>> {
/*!
* \brief returns hash of the optional value.
* \param val value.
* \return hash code.
*/
size_t operator()(const dmlc::optional<T>& val) const {
size_t operator()(const dmlc::optional<T> &val) const {
std::hash<bool> hash_bool;
size_t res = hash_bool(val.has_value());
if (val.has_value()) {
Expand All @@ -368,6 +368,6 @@ struct hash<dmlc::optional<T> > {
return res;
}
};
} // namespace std
} // namespace std

#endif // DMLC_OPTIONAL_H_
#endif // DMLC_OPTIONAL_H_

0 comments on commit 29211ba

Please sign in to comment.