diff --git a/include/xlnt/cell/cell.hpp b/include/xlnt/cell/cell.hpp
index 49ed6402..89fedffc 100644
--- a/include/xlnt/cell/cell.hpp
+++ b/include/xlnt/cell/cell.hpp
@@ -172,7 +172,48 @@ public:
///
bool has_hyperlink() const;
- // style
+ // computed format
+
+ ///
+ /// For each of alignment, border, fill, font, number format, and protection,
+ /// returns a format using the value from the cell format if that value is
+ /// applied, or else the value from the named style if that value is applied,
+ /// or else the default value. This is used to retreive the formatting of the cell
+ /// as it will be displayed in an editing application.
+ ///
+ format get_computed_format() const;
+
+ ///
+ /// Returns the result of get_computed_format().get_alignment().
+ ///
+ alignment get_computed_alignment() const;
+
+ ///
+ /// Returns the result of get_computed_format().get_border().
+ ///
+ border get_computed_border() const;
+
+ ///
+ /// Returns the result of get_computed_format().get_fill().
+ ///
+ fill get_computed_fill() const;
+
+ ///
+ /// Returns the result of get_computed_format().get_font().
+ ///
+ font get_computed_font() const;
+
+ ///
+ /// Returns the result of get_computed_format().get_number_format().
+ ///
+ number_format get_computed_number_format() const;
+
+ ///
+ /// Returns the result of get_computed_format().get_protection().
+ ///
+ protection get_computed_protection() const;
+
+ // format
///
/// Return true if this cell has had a format applied to it.
@@ -181,100 +222,145 @@ public:
///
/// Return a reference to the format applied to this cell.
+ /// If this cell has no format, an invalid_attribute exception will be thrown.
///
- format &get_format();
-
- ///
- /// Return a reference to the format applied to this cell.
- ///
- const format &get_format() const;
+ format get_format() const;
+ ///
+ /// Applies the cell-level formatting of new_format to this cell.
+ ///
void set_format(const format &new_format);
-
- void set_format_id(std::size_t format_id);
+ ///
+ /// Remove the cell-level formatting from this cell.
+ /// This doesn't affect the style that may also be applied to the cell.
+ /// Throws an invalid_attribute exception if no format is applied.
+ ///
void clear_format();
-
- // style
///
- /// Return true if this cell has had a format applied to it.
- ///
- bool has_style() const;
-
- ///
- /// Return a reference to the format applied to this cell.
- ///
- const style &get_style() const;
-
- void set_style(const style &new_style);
-
- void set_style(const std::string &style_name);
-
- void clear_style();
-
- ///
- /// Return the number format of this cell.
+ /// Returns the number format of this cell.
///
const number_format &get_number_format() const;
+ ///
+ /// Creates a new format in the workbook, sets its number_format
+ /// to the given format, and applies the format to this cell.
+ ///
void set_number_format(const number_format &format);
///
- /// Return the font applied to the text in this cell.
+ /// Returns the font applied to the text in this cell.
///
const font &get_font() const;
+ ///
+ /// Creates a new format in the workbook, sets its font
+ /// to the given font, and applies the format to this cell.
+ ///
void set_font(const font &font_);
///
- /// Return the fill applied to this cell.
+ /// Returns the fill applied to this cell.
///
const fill &get_fill() const;
+ ///
+ /// Creates a new format in the workbook, sets its fill
+ /// to the given fill, and applies the format to this cell.
+ ///
void set_fill(const fill &fill_);
///
- /// Return the border of this cell.
+ /// Returns the border of this cell.
///
const border &get_border() const;
+ ///
+ /// Creates a new format in the workbook, sets its border
+ /// to the given border, and applies the format to this cell.
+ ///
void set_border(const border &border_);
///
- /// Return the alignment of the text in this cell.
+ /// Returns the alignment of the text in this cell.
///
const alignment &get_alignment() const;
+ ///
+ /// Creates a new format in the workbook, sets its alignment
+ /// to the given alignment, and applies the format to this cell.
+ ///
void set_alignment(const alignment &alignment_);
///
- /// Return the protection of this cell.
+ /// Returns the protection of this cell.
///
const protection &get_protection() const;
+ ///
+ /// Creates a new format in the workbook, sets its protection
+ /// to the given protection, and applies the format to this cell.
+ ///
void set_protection(const protection &protection_);
- // comment
+ // style
- ///
- /// Return the comment of this cell.
- ///
- comment get_comment();
+ ///
+ /// Returns true if this cell has had a style applied to it.
+ ///
+ bool has_style() const;
- ///
- /// Return the comment of this cell.
- ///
- const comment get_comment() const;
+ ///
+ /// Returns a reference to the named style applied to this cell.
+ ///
+ style get_style() const;
- void set_comment(const comment &comment);
- void clear_comment();
- bool has_comment() const;
+ ///
+ /// Returns the name of the style applied to this cell.
+ ///
+ std::string get_style_name() const;
+
+ ///
+ /// Equivalent to set_style(new_style.name())
+ ///
+ void set_style(const style &new_style);
+
+ ///
+ /// Sets the named style applied to this cell to a style named style_name.
+ /// If this style has not been previously created in the workbook, a
+ /// key_not_found exception will be thrown.
+ ///
+ void set_style(const std::string &style_name);
+
+ ///
+ /// Removes the named style from this cell.
+ /// An invalid_attribute exception will be thrown if this cell has no style.
+ /// This will not affect the cell format of the cell.
+ ///
+ void clear_style();
// formula
+
+ ///
+ /// Returns the string representation of the formula applied to this cell.
+ ///
std::string get_formula() const;
+
+ ///
+ /// Sets the formula of this cell to the given value.
+ /// This formula string should begin with '='.
+ ///
void set_formula(const std::string &formula);
+
+ ///
+ /// Removes the formula from this cell. After this is called, has_formula() will return false.
+ ///
void clear_formula();
+
+ ///
+ /// Returns true if this cell has had a formula applied to it.
+ ///
bool has_formula() const;
// printing
@@ -384,8 +470,6 @@ public:
friend XLNT_FUNCTION std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell);
private:
- std::size_t get_format_id() const;
-
// make these friends so they can use the private constructor
friend class style;
friend class worksheet;
@@ -393,8 +477,18 @@ private:
friend class detail::xlsx_producer;
friend struct detail::cell_impl;
+ ///
+ /// Helper function to guess the type of a string, convert it,
+ /// and then use the correct cell::get_value according to the type.
+ ///
void guess_type_and_set_value(const std::string &value);
+ ///
+ /// Returns a non-const reference to the format of this cell.
+ /// This is for internal use only.
+ ///
+ format &get_format();
+
///
/// Private constructor to create a cell from its implementation.
///
diff --git a/include/xlnt/cell/index_types.hpp b/include/xlnt/cell/index_types.hpp
index 2b66c903..1b4f5f70 100644
--- a/include/xlnt/cell/index_types.hpp
+++ b/include/xlnt/cell/index_types.hpp
@@ -54,7 +54,7 @@ public:
///
/// Excel only supports 1 - 3 letter column names from A->ZZZ, so we
/// restrict our column names to 1 - 3 characters, each in the range A - Z.
- /// Strings outside this range and malformed strings will throw xlnt::column_string_index_exception.
+ /// Strings outside this range and malformed strings will throw column_string_index_exception.
///
static index_t column_index_from_string(const std::string &column_string);
diff --git a/include/xlnt/cell/text_run.hpp b/include/xlnt/cell/text_run.hpp
index a7dba081..823182f5 100644
--- a/include/xlnt/cell/text_run.hpp
+++ b/include/xlnt/cell/text_run.hpp
@@ -63,11 +63,11 @@ public:
private:
std::string string_;
- std::experimental::optional size_;
- std::experimental::optional color_;
- std::experimental::optional font_;
- std::experimental::optional family_;
- std::experimental::optional scheme_;
+ optional size_;
+ optional color_;
+ optional font_;
+ optional family_;
+ optional scheme_;
};
} // namespace xlnt
diff --git a/include/xlnt/styles/alignment.hpp b/include/xlnt/styles/alignment.hpp
index 218e418e..d82be6f1 100644
--- a/include/xlnt/styles/alignment.hpp
+++ b/include/xlnt/styles/alignment.hpp
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
namespace xlnt {
@@ -37,36 +38,40 @@ namespace xlnt {
class XLNT_CLASS alignment : public hashable
{
public:
- bool get_wrap_text() const;
+ optional shrink() const;
- void set_wrap_text(bool wrap_text);
+ alignment &shrink(bool shrink_to_fit);
- bool has_horizontal() const;
+ optional wrap() const;
- horizontal_alignment get_horizontal() const;
+ alignment &wrap(bool wrap_text);
- void set_horizontal(horizontal_alignment horizontal);
+ optional indent() const;
- bool has_vertical() const;
+ alignment &indent(int indent_size);
- vertical_alignment get_vertical() const;
+ optional rotation() const;
- void set_vertical(vertical_alignment vertical);
-
- void set_shrink_to_fit(bool shrink_to_fit);
-
- bool get_shrink_to_fit() const;
+ alignment &rotation(bool text_rotation);
+
+ optional horizontal() const;
+
+ alignment &horizontal(horizontal_alignment horizontal);
+
+ optional vertical() const;
+
+ alignment &vertical(vertical_alignment vertical);
protected:
std::string to_hash_string() const override;
private:
- horizontal_alignment horizontal_ = horizontal_alignment::general;
- vertical_alignment vertical_ = vertical_alignment::bottom;
- int text_rotation_ = 0;
- bool wrap_text_ = false;
- bool shrink_to_fit_ = false;
- int indent_ = 0;
+ optional shrink_to_fit_;
+ optional wrap_text_;
+ optional indent_;
+ optional text_rotation_;
+ optional horizontal_;
+ optional vertical_;
};
} // namespace xlnt
diff --git a/include/xlnt/styles/base_format.hpp b/include/xlnt/styles/base_format.hpp
index 09f7cd9f..e53eaf9e 100644
--- a/include/xlnt/styles/base_format.hpp
+++ b/include/xlnt/styles/base_format.hpp
@@ -33,8 +33,6 @@
namespace xlnt {
-class cell;
-
///
/// Describes the formatting of a particular cell.
///
diff --git a/include/xlnt/styles/border.hpp b/include/xlnt/styles/border.hpp
index ffdfccdd..cd206fb8 100644
--- a/include/xlnt/styles/border.hpp
+++ b/include/xlnt/styles/border.hpp
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
namespace xlnt {
@@ -50,19 +51,6 @@ enum class XLNT_CLASS border_side
} // namespace xlnt
-namespace std {
-
-template<>
-struct hash
-{
- size_t operator()(const xlnt::border_side &k) const
- {
- return static_cast(k);
- }
-};
-
-} // namepsace std
-
namespace xlnt {
///
@@ -71,44 +59,44 @@ namespace xlnt {
class XLNT_CLASS border : public hashable
{
public:
- using side = border_side;
-
class XLNT_CLASS border_property
{
public:
- bool has_color() const;
- const color &get_color() const;
- void set_color(const color &c);
+ optional color() const;
+ border_property &color(const xlnt::color &c);
- bool has_style() const;
- border_style get_style() const;
- void set_style(border_style style);
+ optional style() const;
+ border_property &style(border_style style);
private:
- bool has_color_ = false;
- color color_ = color::black();
-
- bool has_style_ = false;
- border_style style_;
+ optional color_;
+ optional style_;
};
- static const std::vector> &get_side_names();
+ static const std::vector &all_sides();
border();
- bool has_side(side s) const;
- const border_property &get_side(side s) const;
- void set_side(side s, const border_property &prop);
+ optional side(border_side s) const;
+ border &side(border_side s, const border_property &prop);
+
+ optional diagonal() const;
+ border &diagonal(diagonal_direction dir);
protected:
std::string to_hash_string() const override;
private:
- std::unordered_map sides_;
- /*
- bool outline_ = true;
- diagonal_direction diagonal_direction_ = diagonal_direction::neither;
- */
+ optional start_;
+ optional end_;
+ optional top_;
+ optional bottom_;
+ optional vertical_;
+ optional horizontal_;
+ optional diagonal_;
+
+ //bool outline_ = true;
+ optional diagonal_direction_;
};
} // namespace xlnt
diff --git a/include/xlnt/styles/fill.hpp b/include/xlnt/styles/fill.hpp
index c6a24bd0..a7cffb01 100644
--- a/include/xlnt/styles/fill.hpp
+++ b/include/xlnt/styles/fill.hpp
@@ -31,114 +31,115 @@
namespace xlnt {
+enum class XLNT_CLASS pattern_fill_type
+{
+ none,
+ solid,
+ mediumgray,
+ darkgray,
+ lightgray,
+ darkhorizontal,
+ darkvertical,
+ darkdown,
+ darkup,
+ darkgrid,
+ darktrellis,
+ lighthorizontal,
+ lightvertical,
+ lightdown,
+ lightup,
+ lightgrid,
+ lighttrellis,
+ gray125,
+ gray0625
+};
+
class XLNT_CLASS pattern_fill : public hashable
{
public:
- enum class type
- {
- none,
- solid,
- mediumgray,
- darkgray,
- lightgray,
- darkhorizontal,
- darkvertical,
- darkdown,
- darkup,
- darkgrid,
- darktrellis,
- lighthorizontal,
- lightvertical,
- lightdown,
- lightup,
- lightgrid,
- lighttrellis,
- gray125,
- gray0625
- };
-
pattern_fill();
- pattern_fill(type pattern_type);
+ pattern_fill_type type() const;
- type get_type() const;
+ pattern_fill &type(pattern_fill_type new_type);
- void set_type(type pattern_type);
+ optional foreground() const;
- void set_foreground_color(const color &c);
-
- std::experimental::optional &get_foreground_color();
-
- const std::experimental::optional &get_foreground_color() const;
+ pattern_fill &foreground(const color &foreground);
- void set_background_color(const color &c);
+ optional background() const;
- std::experimental::optional &get_background_color();
-
- const std::experimental::optional &get_background_color() const;
+ pattern_fill &background(const color &background);
protected:
std::string to_hash_string() const override;
private:
- type type_ = type::none;
+ pattern_fill_type type_ = pattern_fill_type::none;
- std::experimental::optional foreground_color_;
- std::experimental::optional background_color_;
+ optional foreground_;
+ optional background_;
+};
+
+enum class XLNT_CLASS gradient_fill_type
+{
+ linear,
+ path
};
class XLNT_CLASS gradient_fill : public hashable
{
public:
- enum class type
- {
- linear,
- path
- };
-
gradient_fill();
- gradient_fill(type gradient_type);
+ gradient_fill_type type() const;
- type get_type() const;
+ // Type
+ gradient_fill &type(gradient_fill_type new_type);
- void set_type(type gradient_type);
+ // Degree
- void set_degree(double degree);
+ gradient_fill °ree(double degree);
- double get_degree() const;
+ double degree() const;
- double get_gradient_left() const;
+ // Left
- void set_gradient_left(double value);
+ double left() const;
- double get_gradient_right() const;
+ gradient_fill &left(double value);
- void set_gradient_right(double value);
+ // Right
- double get_gradient_top() const;
+ double right() const;
- void set_gradient_top(double value);
+ gradient_fill &right(double value);
- double get_gradient_bottom() const;
+ // Top
- void set_gradient_bottom(double value);
+ double top() const;
- void add_stop(double position, color stop_color);
+ gradient_fill &top(double value);
- void delete_stop(double position);
+ // Bottom
- void clear_stops();
+ double bottom() const;
+
+ gradient_fill &bottom(double value);
+
+ // Stops
+
+ gradient_fill &add_stop(double position, color stop_color);
+
+ gradient_fill &clear_stops();
- const std::unordered_map &get_stops() const;
+ std::unordered_map stops() const;
protected:
std::string to_hash_string() const override;
private:
- type type_ = type::linear;
-
- std::unordered_map stops_;
+ gradient_fill_type type_ = gradient_fill_type::linear;
double degree_ = 0;
@@ -146,6 +147,14 @@ private:
double right_ = 0;
double top_ = 0;
double bottom_ = 0;
+
+ std::unordered_map stops_;
+};
+
+enum class XLNT_CLASS fill_type
+{
+ pattern,
+ gradient
};
///
@@ -154,33 +163,46 @@ private:
class XLNT_CLASS fill : public hashable
{
public:
- enum class type
- {
- pattern,
- gradient
- };
+ ///
+ /// Constructs a fill initialized as a none-type pattern fill with no
+ /// foreground or background colors.
+ ///
+ fill();
- static fill gradient(gradient_fill::type gradient_type);
+ ///
+ /// Constructs a fill initialized as a pattern fill based on the given pattern.
+ ///
+ fill(const pattern_fill &pattern);
- static fill pattern(pattern_fill::type pattern_type);
+ ///
+ /// Constructs a fill initialized as a gradient fill based on the given gradient.
+ ///
+ fill(const gradient_fill &gradient);
- type get_type() const;
+ ///
+ /// Returns the fill_type of this fill depending on how it was constructed.
+ ///
+ fill_type type() const;
- gradient_fill &get_gradient_fill();
+ ///
+ /// Returns the gradient fill represented by this fill.
+ /// Throws an invalid_attribute exception if this is not a gradient fill.
+ ///
+ gradient_fill gradient_fill() const;
- const gradient_fill &get_gradient_fill() const;
-
- pattern_fill &get_pattern_fill();
-
- const pattern_fill &get_pattern_fill() const;
+ ///
+ /// Returns the pattern fill represented by this fill.
+ /// Throws an invalid_attribute exception if this is not a pattern fill.
+ ///
+ pattern_fill pattern_fill() const;
protected:
std::string to_hash_string() const override;
private:
- type type_ = type::pattern;
- gradient_fill gradient_;
- pattern_fill pattern_;
+ fill_type type_ = fill_type::pattern;
+ xlnt::gradient_fill gradient_;
+ xlnt::pattern_fill pattern_;
};
} // namespace xlnt
diff --git a/include/xlnt/styles/font.hpp b/include/xlnt/styles/font.hpp
index b9ce5d98..a3af7f55 100644
--- a/include/xlnt/styles/font.hpp
+++ b/include/xlnt/styles/font.hpp
@@ -27,7 +27,7 @@
#include
#include
-#include
+#include
namespace xlnt {
@@ -50,47 +50,43 @@ public:
font();
- void set_bold(bool bold);
+ font &bold(bool bold);
- bool is_bold() const;
+ bool bold() const;
- void set_italic(bool italic);
+ font &italic(bool italic);
- bool is_italic() const;
+ bool italic() const;
- void set_strikethrough(bool strikethrough);
+ font &strikethrough(bool strikethrough);
- bool is_strikethrough() const;
+ bool strikethrough() const;
- void set_underline(underline_style new_underline);
+ font &underline(underline_style new_underline);
- bool is_underline() const;
+ bool underlined() const;
- underline_style get_underline() const;
+ underline_style underline() const;
- void set_size(std::size_t size);
+ font &size(std::size_t size);
- std::size_t get_size() const;
+ std::size_t size() const;
- void set_name(const std::string &name);
+ font &name(const std::string &name);
- std::string get_name() const;
+ std::string name() const;
- void set_color(color c);
+ font &color(const color &c);
- void set_family(std::size_t family);
+ optional color() const;
- bool has_scheme() const;
+ font &family(std::size_t family);
- void set_scheme(const std::string &scheme);
+ optional family() const;
- std::string get_scheme() const;
+ font &scheme(const std::string &scheme);
- color get_color() const;
-
- bool has_family() const;
-
- std::size_t get_family() const;
+ optional scheme() const;
protected:
std::string to_hash_string() const override;
@@ -104,13 +100,11 @@ private:
bool italic_ = false;
bool superscript_ = false;
bool subscript_ = false;
- underline_style underline_ = underline_style::none;
bool strikethrough_ = false;
- color color_ = theme_color(1);
- bool has_family_ = true;
- std::size_t family_ = 2;
- bool has_scheme_ = true;
- std::string scheme_ = "minor";
+ underline_style underline_ = underline_style::none;
+ optional color_;
+ optional family_;
+ optional scheme_;
};
} // namespace xlnt
diff --git a/include/xlnt/styles/format.hpp b/include/xlnt/styles/format.hpp
index a8bb05f5..2ecd285c 100644
--- a/include/xlnt/styles/format.hpp
+++ b/include/xlnt/styles/format.hpp
@@ -1,5 +1,4 @@
// Copyright (c) 2014-2016 Thomas Fussell
-// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -23,25 +22,58 @@
// @author: see AUTHORS file
#pragma once
-#include
+#include
+#include
+
+#include
namespace xlnt {
-class style;
-namespace detail { struct workbook_impl; }
+class alignment;
+class border;
+class fill;
+class font;
+class number_format;
+class protection;
+
+namespace detail {
+struct format_impl;
+struct stylesheet;
+} // namespace detail
///
/// Describes the formatting of a particular cell.
///
-class XLNT_CLASS format : public base_format
+class XLNT_CLASS format
{
public:
- format();
- format(const format &other);
- format &operator=(const format &other);
-
-protected:
- std::string to_hash_string() const override;
+ std::size_t get_id() const;
+
+ alignment get_alignment() const;
+ void set_alignment(const alignment &new_alignment);
+
+ border get_border() const;
+ void set_border(const border &new_border);
+
+ fill get_fill() const;
+ void set_fill(const fill &new_fill);
+
+ font get_font() const;
+ void set_font(const font &new_font);
+
+ number_format get_number_format() const;
+ void set_number_format(const number_format &new_number_format);
+
+ protection get_protection() const;
+ void set_protection(const protection &new_protection);
+
+ void set_style(const std::string &name);
+ std::string get_name() const;
+
+private:
+ friend struct detail::stylesheet;
+ format(detail::format_impl *d);
+ detail::format_impl *d_;
};
} // namespace xlnt
diff --git a/include/xlnt/styles/protection.hpp b/include/xlnt/styles/protection.hpp
index 4f06822f..80ee259a 100644
--- a/include/xlnt/styles/protection.hpp
+++ b/include/xlnt/styles/protection.hpp
@@ -27,6 +27,7 @@
#include
#include
+#include
namespace xlnt {
@@ -36,14 +37,18 @@ namespace xlnt {
class XLNT_CLASS protection : public hashable
{
public:
- protection();
- protection(bool locked, bool hidden);
+ static protection unlocked_and_visible();
+ static protection locked_and_visible();
+ static protection unlocked_and_hidden();
+ static protection locked_and_hidden();
- bool get_locked() const;
- void set_locked(bool locked);
+ protection();
+
+ bool locked() const;
+ protection &locked(bool locked);
- bool get_hidden() const;
- void set_hidden(bool hidden);
+ bool hidden() const;
+ protection &hidden(bool hidden);
protected:
std::string to_hash_string() const override;
diff --git a/include/xlnt/styles/style.hpp b/include/xlnt/styles/style.hpp
index 9f219b0e..9a5bd840 100644
--- a/include/xlnt/styles/style.hpp
+++ b/include/xlnt/styles/style.hpp
@@ -30,35 +30,34 @@
namespace xlnt {
-class workbook;
+namespace detail {
+struct style_impl;
+struct stylesheet;
+}
///
/// Describes a style which has a name and can be applied to multiple individual
/// formats. In Excel this is a "Cell Style".
///
-class XLNT_CLASS style : public base_format
+class XLNT_CLASS style
{
public:
- style();
- style(const style &other);
- style &operator=(const style &other);
-
- std::string get_name() const;
- void set_name(const std::string &name);
+ std::string name() const;
+ style &name(const std::string &name);
- bool get_hidden() const;
- void set_hidden(bool value);
-
- std::size_t get_builtin_id() const;
- void set_builtin_id(std::size_t builtin_id);
+ bool hidden() const;
+ style &hidden(bool value);
-protected:
- std::string to_hash_string() const override;
+ bool custom() const;
+ style &custom(bool value);
+
+ std::size_t built_in_id() const;
+ style &built_in_id(std::size_t builtin_id);
private:
- std::string name_;
- bool hidden_;
- std::size_t builtin_id_;
+ friend struct detail::stylesheet;
+ style(detail::style_impl *d);
+ detail::style_impl *d_;
};
} // namespace xlnt
diff --git a/include/xlnt/utils/datetime.hpp b/include/xlnt/utils/datetime.hpp
index dc03e23e..46ab8787 100644
--- a/include/xlnt/utils/datetime.hpp
+++ b/include/xlnt/utils/datetime.hpp
@@ -29,6 +29,9 @@
namespace xlnt {
+struct date;
+struct time;
+
///
/// A datetime is a combination of a date and a time.
///
@@ -52,6 +55,7 @@ struct XLNT_CLASS datetime
///
static datetime from_number(long double number, calendar base_date);
+ datetime(const date &d, const time &t);
datetime(int year_, int month_, int day_, int hour_ = 0, int minute_ = 0, int second_ = 0, int microsecond_ = 0);
std::string to_string() const;
diff --git a/include/xlnt/utils/optional.hpp b/include/xlnt/utils/optional.hpp
index 99565f50..e84a8a76 100644
--- a/include/xlnt/utils/optional.hpp
+++ b/include/xlnt/utils/optional.hpp
@@ -1,1042 +1,87 @@
-// Copyright (C) 2011 - 2012 Andrzej Krzemienski.
-//
-// Use, modification, and distribution is subject to the Boost Software
-// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-// The idea and interface is based on Boost.Optional library
-// authored by Fernando Luis Cacciola Carballal
+#pragma once
-# ifndef ___OPTIONAL_HPP___
-# define ___OPTIONAL_HPP___
+#include
+#include
-# include
-# include
-# include
-# include
-# include
-# include
-# include
+namespace xlnt {
-# define TR2_OPTIONAL_REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false
-
-# if defined __GNUC__ // NOTE: GNUC is also defined for Clang
-# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
-# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
-# elif (__GNUC__ > 4)
-# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
-# endif
-#
-# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)
-# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
-# elif (__GNUC__ > 4)
-# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
-# endif
-#
-# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1)
-# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
-# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
-# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
-# elif (__GNUC__ > 4)
-# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
-# endif
-# endif
-#
-# if defined __clang_major__
-# if (__clang_major__ == 3 && __clang_minor__ >= 5)
-# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
-# elif (__clang_major__ > 3)
-# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
-# endif
-# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
-# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
-# elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2)
-# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
-# endif
-# endif
-#
-# if defined _MSC_VER
-# if (_MSC_VER >= 1900)
-# define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
-# endif
-# endif
-
-# if defined __clang__
-# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9)
-# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
-# else
-# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
-# endif
-# elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
-# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
-# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
-# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
-# else
-# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
-# endif
-
-
-# if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
-# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1
-# define OPTIONAL_CONSTEXPR_INIT_LIST constexpr
-# else
-# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0
-# define OPTIONAL_CONSTEXPR_INIT_LIST
-# endif
-
-# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L)
-# define OPTIONAL_HAS_MOVE_ACCESSORS 1
-# else
-# define OPTIONAL_HAS_MOVE_ACCESSORS 0
-# endif
-
-# // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr
-# if (defined __cplusplus) && (__cplusplus == 201103L)
-# define OPTIONAL_MUTABLE_CONSTEXPR
-# else
-# define OPTIONAL_MUTABLE_CONSTEXPR constexpr
-# endif
-
-namespace std{
-
-namespace experimental{
-
-// BEGIN workaround for missing is_trivially_destructible
-# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
- // leave it: it is already there
-# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
- // leave it: it is already there
-# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
- // leave it: it is already there
-# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
- // leave it: the user doesn't want it
-# else
- template
- using is_trivially_destructible = std::has_trivial_destructor;
-# endif
-// END workaround for missing is_trivially_destructible
-
-# if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___)
- // leave it; our metafunctions are already defined.
-# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
- // leave it; our metafunctions are already defined.
-# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
- // leave it: it is already there
-# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
- // leave it: the user doesn't want it
-# else
-
-
-// workaround for missing traits in GCC and CLANG
-template
-struct is_nothrow_move_constructible
+template
+class XLNT_CLASS optional
{
- constexpr static bool value = std::is_nothrow_constructible::value;
-};
-
-
-template
-struct is_assignable
-{
- template
- constexpr static bool has_assign(...) { return false; }
-
- template () = std::declval(), true)) >
- // the comma operator is necessary for the cases where operator= returns void
- constexpr static bool has_assign(bool) { return true; }
-
- constexpr static bool value = has_assign(true);
-};
-
-
-template
-struct is_nothrow_move_assignable
-{
- template
- struct has_nothrow_move_assign {
- constexpr static bool value = false;
- };
-
- template
- struct has_nothrow_move_assign {
- constexpr static bool value = noexcept( std::declval() = std::declval() );
- };
-
- constexpr static bool value = has_nothrow_move_assign::value>::value;
-};
-// end workaround
-
-
-# endif
-
-
-
-// 20.5.4, optional for object types
-template class optional;
-
-// 20.5.5, optional for lvalue reference types
-template class optional;
-
-
-// workaround: std utility functions aren't constexpr yet
-template inline constexpr T&& constexpr_forward(typename std::remove_reference::type& t) noexcept
-{
- return static_cast(t);
-}
-
-template inline constexpr T&& constexpr_forward(typename std::remove_reference::type&& t) noexcept
-{
- static_assert(!std::is_lvalue_reference::value, "!!");
- return static_cast(t);
-}
-
-template inline constexpr typename std::remove_reference::type&& constexpr_move(T&& t) noexcept
-{
- return static_cast::type&&>(t);
-}
-
-
-#if defined NDEBUG
-# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
-#else
-# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR)))
-#endif
-
-
-namespace detail_
-{
-
-// static_addressof: a constexpr version of addressof
-template
-struct has_overloaded_addressof
-{
- template
- constexpr static bool has_overload(...) { return false; }
-
- template ().operator&()) >
- constexpr static bool has_overload(bool) { return true; }
-
- constexpr static bool value = has_overload(true);
-};
-
-template )>
-constexpr T* static_addressof(T& ref)
-{
- return &ref;
-}
-
-template )>
-T* static_addressof(T& ref)
-{
- return std::addressof(ref);
-}
-
-
-// the call to convert(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A
-template
-U convert(U v) { return v; }
-
-} // namespace detail
-
-
-constexpr struct trivial_init_t{} trivial_init{};
-
-
-// 20.5.6, In-place construction
-constexpr struct in_place_t{} in_place{};
-
-
-// 20.5.7, Disengaged state indicator
-struct nullopt_t
-{
- struct init{};
- constexpr explicit nullopt_t(init){}
-};
-constexpr nullopt_t nullopt{nullopt_t::init()};
-
-
-// 20.5.8, class bad_optional_access
-class bad_optional_access : public logic_error {
public:
- explicit bad_optional_access(const string& what_arg) : logic_error{what_arg} {}
- explicit bad_optional_access(const char* what_arg) : logic_error{what_arg} {}
+ optional() : has_value_(false)
+ {
+ }
+
+ optional(const T &value) : has_value_(true), value_(value)
+ {
+ }
+
+ operator bool() const
+ {
+ return is_set();
+ }
+
+ bool is_set() const
+ {
+ return has_value_;
+ }
+
+ void set(const T &value)
+ {
+ has_value_ = true;
+ value_ = value;
+ }
+
+ T &operator*()
+ {
+ return get();
+ }
+
+ const T &operator*() const
+ {
+ return get();
+ }
+
+ T *operator->()
+ {
+ return &get();
+ }
+
+ const T *operator->() const
+ {
+ return &get();
+ }
+
+ T &get()
+ {
+ if (!has_value_)
+ {
+ throw invalid_attribute();
+ }
+
+ return value_;
+ }
+
+ const T &get() const
+ {
+ if (!has_value_)
+ {
+ throw invalid_attribute();
+ }
+
+ return value_;
+ }
+
+ void clear()
+ {
+ has_value_ = false;
+ value_ = T();
+ }
+
+private:
+ bool has_value_;
+ T value_;
};
-
-template
-union storage_t
-{
- unsigned char dummy_;
- T value_;
-
- constexpr storage_t( trivial_init_t ) noexcept : dummy_() {};
-
- template
- constexpr storage_t( Args&&... args ) : value_(constexpr_forward(args)...) {}
-
- ~storage_t(){}
-};
-
-
-template
-union constexpr_storage_t
-{
- unsigned char dummy_;
- T value_;
-
- constexpr constexpr_storage_t( trivial_init_t ) noexcept : dummy_() {};
-
- template
- constexpr constexpr_storage_t( Args&&... args ) : value_(constexpr_forward(args)...) {}
-
- ~constexpr_storage_t() = default;
-};
-
-
-template
-struct optional_base
-{
- bool init_;
- storage_t storage_;
-
- constexpr optional_base() noexcept : init_(false), storage_(trivial_init) {};
-
- explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {}
-
- explicit constexpr optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {}
-
- template explicit optional_base(in_place_t, Args&&... args)
- : init_(true), storage_(constexpr_forward(args)...) {}
-
- template >)>
- explicit optional_base(in_place_t, std::initializer_list il, Args&&... args)
- : init_(true), storage_(il, std::forward(args)...) {}
-
- ~optional_base() { if (init_) storage_.value_.T::~T(); }
-};
-
-
-template
-struct constexpr_optional_base
-{
- bool init_;
- constexpr_storage_t storage_;
-
- constexpr constexpr_optional_base() noexcept : init_(false), storage_(trivial_init) {};
-
- explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_(v) {}
-
- explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {}
-
- template explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
- : init_(true), storage_(constexpr_forward(args)...) {}
-
- template >)>
- OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, std::initializer_list il, Args&&... args)
- : init_(true), storage_(il, std::forward(args)...) {}
-
- ~constexpr_optional_base() = default;
-};
-
-template
-using OptionalBase = typename std::conditional<
- is_trivially_destructible::value,
- constexpr_optional_base,
- optional_base
->::type;
-
-
-
-template
-class optional : private OptionalBase
-{
- static_assert( !std::is_same::type, nullopt_t>::value, "bad T" );
- static_assert( !std::is_same::type, in_place_t>::value, "bad T" );
-
-
- constexpr bool initialized() const noexcept { return OptionalBase::init_; }
- T* dataptr() { return std::addressof(OptionalBase::storage_.value_); }
- constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase::storage_.value_); }
-
-# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
- constexpr const T& contained_val() const& { return OptionalBase::storage_.value_; }
-# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
- OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return std::move(OptionalBase::storage_.value_); }
- OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase::storage_.value_; }
-# else
- T& contained_val() & { return OptionalBase::storage_.value_; }
- T&& contained_val() && { return std::move(OptionalBase::storage_.value_); }
-# endif
-# else
- constexpr const T& contained_val() const { return OptionalBase::storage_.value_; }
- T& contained_val() { return OptionalBase::storage_.value_; }
-# endif
-
- void clear() noexcept {
- if (initialized()) dataptr()->T::~T();
- OptionalBase::init_ = false;
- }
-
- template
- void initialize(Args&&... args) noexcept(noexcept(T(std::forward(args)...)))
- {
- assert(!OptionalBase::init_);
- ::new (static_cast(dataptr())) T(std::forward(args)...);
- OptionalBase::init_ = true;
- }
-
- template
- void initialize(std::initializer_list il, Args&&... args) noexcept(noexcept(T(il, std::forward(args)...)))
- {
- assert(!OptionalBase::init_);
- ::new (static_cast(dataptr())) T(il, std::forward(args)...);
- OptionalBase::init_ = true;
- }
-
-public:
- typedef T value_type;
-
- // 20.5.5.1, constructors
- constexpr optional() noexcept : OptionalBase() {};
- constexpr optional(nullopt_t) noexcept : OptionalBase() {};
-
- optional(const optional& rhs)
- : OptionalBase()
- {
- if (rhs.initialized()) {
- ::new (static_cast(dataptr())) T(*rhs);
- OptionalBase::init_ = true;
- }
- }
-
- optional(optional&& rhs) noexcept(is_nothrow_move_constructible::value)
- : OptionalBase()
- {
- if (rhs.initialized()) {
- ::new (static_cast(dataptr())) T(std::move(*rhs));
- OptionalBase::init_ = true;
- }
- }
-
- constexpr optional(const T& v) : OptionalBase(v) {}
-
- constexpr optional(T&& v) : OptionalBase(constexpr_move(v)) {}
-
- template
- explicit constexpr optional(in_place_t, Args&&... args)
- : OptionalBase(in_place_t{}, constexpr_forward(args)...) {}
-
- template >)>
- OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, std::initializer_list il, Args&&... args)
- : OptionalBase(in_place_t{}, il, constexpr_forward(args)...) {}
-
- // 20.5.4.2, Destructor
- ~optional() = default;
-
- // 20.5.4.3, assignment
- optional& operator=(nullopt_t) noexcept
- {
- clear();
- return *this;
- }
-
- optional& operator=(const optional& rhs)
- {
- if (initialized() == true && rhs.initialized() == false) clear();
- else if (initialized() == false && rhs.initialized() == true) initialize(*rhs);
- else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs;
- return *this;
- }
-
- optional& operator=(optional&& rhs)
- noexcept(is_nothrow_move_assignable::value && is_nothrow_move_constructible::value)
- {
- if (initialized() == true && rhs.initialized() == false) clear();
- else if (initialized() == false && rhs.initialized() == true) initialize(std::move(*rhs));
- else if (initialized() == true && rhs.initialized() == true) contained_val() = std::move(*rhs);
- return *this;
- }
-
- template
- auto operator=(U&& v)
- -> typename enable_if
- <
- is_same::type, T>::value,
- optional&
- >::type
- {
- if (initialized()) { contained_val() = std::forward(v); }
- else { initialize(std::forward(v)); }
- return *this;
- }
-
-
- template
- void emplace(Args&&... args)
- {
- clear();
- initialize(std::forward(args)...);
- }
-
- template
- void emplace(initializer_list il, Args&&... args)
- {
- clear();
- initialize(il, std::forward(args)...);
- }
-
- // 20.5.4.4, Swap
- void swap(optional& rhs) noexcept(is_nothrow_move_constructible::value && noexcept(swap(declval(), declval())))
- {
- if (initialized() == true && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); }
- else if (initialized() == false && rhs.initialized() == true) { initialize(std::move(*rhs)); rhs.clear(); }
- else if (initialized() == true && rhs.initialized() == true) { using std::swap; swap(**this, *rhs); }
- }
-
- // 20.5.4.5, Observers
-
- explicit constexpr operator bool() const noexcept { return initialized(); }
-
- constexpr T const* operator ->() const {
- return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr());
- }
-
-# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
-
- OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
- assert (initialized());
- return dataptr();
- }
-
- constexpr T const& operator *() const& {
- return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
- }
-
- OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
- assert (initialized());
- return contained_val();
- }
-
- OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
- assert (initialized());
- return constexpr_move(contained_val());
- }
-
- constexpr T const& value() const& {
- return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
- }
-
- OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
- return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
- }
-
- OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
- if (!initialized()) throw bad_optional_access("bad optional access");
- return std::move(contained_val());
- }
-
-# else
-
- T* operator ->() {
- assert (initialized());
- return dataptr();
- }
-
- constexpr T const& operator *() const {
- return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
- }
-
- T& operator *() {
- assert (initialized());
- return contained_val();
- }
-
- constexpr T const& value() const {
- return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
- }
-
- T& value() {
- return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
- }
-
-# endif
-
-# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
-
- template
- constexpr T value_or(V&& v) const&
- {
- return *this ? **this : detail_::convert(constexpr_forward(v));
- }
-
-# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
-
- template
- OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) &&
- {
- return *this ? constexpr_move(const_cast&>(*this).contained_val()) : detail_::convert(constexpr_forward(v));
- }
-
-# else
-
- template
- T value_or(V&& v) &&
- {
- return *this ? constexpr_move(const_cast&>(*this).contained_val()) : detail_::convert(constexpr_forward(v));
- }
-
-# endif
-
-# else
-
- template
- constexpr T value_or(V&& v) const
- {
- return *this ? **this : detail_::convert(constexpr_forward(v));
- }
-
-# endif
-
-};
-
-
-template
-class optional
-{
- static_assert( !std::is_same::value, "bad T" );
- static_assert( !std::is_same::value, "bad T" );
- T* ref;
-
-public:
-
- // 20.5.5.1, construction/destruction
- constexpr optional() noexcept : ref(nullptr) {}
-
- constexpr optional(nullopt_t) noexcept : ref(nullptr) {}
-
- constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {}
-
- optional(T&&) = delete;
-
- constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {}
-
- explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {}
-
- explicit optional(in_place_t, T&&) = delete;
-
- ~optional() = default;
-
- // 20.5.5.2, mutation
- optional& operator=(nullopt_t) noexcept {
- ref = nullptr;
- return *this;
- }
-
- // optional& operator=(const optional& rhs) noexcept {
- // ref = rhs.ref;
- // return *this;
- // }
-
- // optional& operator=(optional&& rhs) noexcept {
- // ref = rhs.ref;
- // return *this;
- // }
-
- template
- auto operator=(U&& rhs) noexcept
- -> typename enable_if
- <
- is_same::type, optional>::value,
- optional&
- >::type
- {
- ref = rhs.ref;
- return *this;
- }
-
- template
- auto operator=(U&& rhs) noexcept
- -> typename enable_if
- <
- !is_same::type, optional>::value,
- optional&
- >::type
- = delete;
-
- void emplace(T& v) noexcept {
- ref = detail_::static_addressof(v);
- }
-
- void emplace(T&&) = delete;
-
-
- void swap(optional& rhs) noexcept
- {
- std::swap(ref, rhs.ref);
- }
-
- // 20.5.5.3, observers
- constexpr T* operator->() const {
- return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
- }
-
- constexpr T& operator*() const {
- return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
- }
-
- constexpr T& value() const {
- return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
- }
-
- explicit constexpr operator bool() const noexcept {
- return ref != nullptr;
- }
-
- template
- constexpr typename decay::type value_or(V&& v) const
- {
- return *this ? **this : detail_::convert::type>(constexpr_forward(v));
- }
-};
-
-
-template
-class optional
-{
- static_assert( sizeof(T) == 0, "optional rvalue references disallowed" );
-};
-
-
-// 20.5.8, Relational operators
-template constexpr bool operator==(const optional& x, const optional& y)
-{
- return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
-}
-
-template constexpr bool operator!=(const optional& x, const optional& y)
-{
- return !(x == y);
-}
-
-template constexpr bool operator<(const optional& x, const optional& y)
-{
- return (!y) ? false : (!x) ? true : *x < *y;
-}
-
-template constexpr bool operator>(const optional& x, const optional& y)
-{
- return (y < x);
-}
-
-template constexpr bool operator<=(const optional& x, const optional& y)
-{
- return !(y < x);
-}
-
-template constexpr bool operator>=(const optional& x, const optional& y)
-{
- return !(x < y);
-}
-
-
-// 20.5.9, Comparison with nullopt
-template constexpr bool operator==(const optional& x, nullopt_t) noexcept
-{
- return (!x);
-}
-
-template constexpr bool operator==(nullopt_t, const optional& x) noexcept
-{
- return (!x);
-}
-
-template constexpr bool operator!=(const optional& x, nullopt_t) noexcept
-{
- return bool(x);
-}
-
-template constexpr bool operator!=(nullopt_t, const optional