Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Commit 2019-02-20 - Minor documentation updates.
  • cxxomfort: Updated /doc/trunk/cxxomfort/LICENSE.txt.
  • cxxomfort: Deprecated some extras/ headers.
  • cxxomfort: Removed the extras/ headers for array_ref, foreach, forward_list and optional.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | trunk | y2019
Files: files | file ages | folders
SHA3-256:65b214ce714e74870eaa003a01a0c84198cdddd23ff88af96db6fa7dc531322c
User & Date: luismachuca 2019-02-20 13:34:38
Context
2019-02-20
13:34
Commit 2019-02-20 - Minor documentation updates.
  • cxxomfort: Updated /doc/trunk/cxxomfort/LICENSE.txt.
  • cxxomfort: Deprecated some extras/ headers.
  • cxxomfort: Removed the extras/ headers for array_ref, foreach, forward_list and optional.
Leaf check-in: 65b214ce user: luismachuca tags: trunk, y2019
2019-02-16
04:45
Commit 2019-02-15 - Love++ for strings of documentation.
  • cxxomfort: Improved code documentation.
  • cxxomfort: Added Doxygen-generated documentation (see below).
  • memory: Added detection of shared_ptr and other <tr1/memory> utilities for GCC.
  • string: Added missing output operator to std::string under Watcom (enhances: [b8ea55b791]).
  • string: Added to_string support under Watcom (enhances: [b8ea55b791]).
  • string: Added to_string support under MSVC 2005.
  • typeindex: Added minimum std::type_index support under Watcom (enhances: [b8ea55b791]).
  • typeindex: Added minimum std::type_index support under MSVC 2005.

Starting this revision cxxomfort offers a copy of the Doxygen generated documentation for the interfaces via unversioned files. The contents are reachable via /uv/html/.

While compilers like MSVC 2005 and OpenWatcom do not have TR1 and thus are not supported, the current build organizes things so that more of the core features can be used before a hard fail. In particular, byte, declval, string_view, to_string and in the future in a limited manner reference_wrapper, errc and unique_ptr should be at least minimally usable. check-in: b1a27cd4 user: luismachuca tags: trunk

Changes

Changes to cxxomfort/CHANGELOG.txt.








1
2
3
4
5
6
7







Commit 2019-02-15 - <tt>Love++</tt> for strings of documentation.

  *  cxxomfort: Improved code documentation.
  *  cxxomfort: Added Doxygen-generated documentation (see below).
  *  memory: Added detection of shared_ptr and other <tt><tr1/memory></tt> utilities for GCC.
  *  string: Added missing output operator to <tt>std::string</tt> under Watcom (enhances: [b8ea55b791]).
  *  string: Added to_string support under Watcom (enhances: [b8ea55b791]).
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
Commit 2019-02-20 - Minor documentation updates.

  *  cxxomfort: Updated [/doc/trunk/cxxomfort/LICENSE.txt].
  *  cxxomfort: Deprecated some <tt>extras/</tt> headers.
  *  cxxomfort: <b>Removed</b> the <tt>extras/</tt> headers for array_ref, foreach, forward_list and optional.


Commit 2019-02-15 - <tt>Love++</tt> for strings of documentation.

  *  cxxomfort: Improved code documentation.
  *  cxxomfort: Added Doxygen-generated documentation (see below).
  *  memory: Added detection of shared_ptr and other <tt><tr1/memory></tt> utilities for GCC.
  *  string: Added missing output operator to <tt>std::string</tt> under Watcom (enhances: [b8ea55b791]).
  *  string: Added to_string support under Watcom (enhances: [b8ea55b791]).

Changes to cxxomfort/LICENSE.txt.

1
2
3
4
5
6
7
8
9
cxxcomfort Library for C++
Copyright (c) 2012,2017 Luis Machuca Bezzaza and various authors

Permission is hereby granted, free of charge, to any person obtaining 
a copy of this software and associated documentation 
files (the "Software"), to deal in the Software without restriction, 
including without limitation the rights to use, copy, modify, merge, 
publish, distribute, sublicense, and/or sell copies of the Software, 
and to permit persons to whom the Software is furnished to do so, 
|
|







1
2
3
4
5
6
7
8
9
cxxomfort Library for C++
Copyright (c) 2012-2019 Luis Machuca Bezzaza, credits to various authors

Permission is hereby granted, free of charge, to any person obtaining 
a copy of this software and associated documentation 
files (the "Software"), to deal in the Software without restriction, 
including without limitation the rights to use, copy, modify, merge, 
publish, distribute, sublicense, and/or sell copies of the Software, 
and to permit persons to whom the Software is furnished to do so, 

Deleted cxxomfort/cxxomfort/extras/array_ref.hpp.

1
2
3
4
5
6
#ifndef CXXOMFORT_EXTRAS_ARRAY_REF_HPP
#define CXXOMFORT_EXTRAS_ARRAY_REF_HPP
#include <cxxomfort/base.hpp>
#pragma message CXXO_WARNING("deprecated header. New header is <cxxomfort/library/array_ref.hpp>")
#include <cxxomfort/library/array_ref.hpp>
#endif
<
<
<
<
<
<












Deleted cxxomfort/cxxomfort/extras/auto-impl.hpp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#ifndef CXXOMFORT_EXTRAS_AUTO_IMPL_HPP
#define CXXOMFORT_EXTRAS_AUTO_IMPL_HPP
// see: http://www.nedproductions.biz/blog/implementing-typeof-in-microsofts-c-compiler
#if defined(_MSC_VER) && (_MSC_VER>=1400)
#pragma message CXXO_NOTICE("(MSVC hack for auto)")

namespace msvc_typeof_impl {
	/* This is a fusion of Igor Chesnokov's method (http://rsdn.ru/forum/src/1094305.aspx)
	and Steven Watanabe's method (http://lists.boost.org/Archives/boost/2006/12/115006.php)

	How it works:
	C++ allows template type inference for templated function parameters but nothing else.
	What we do is to pass the expression sent to typeof() into the templated function vartypeID()
	as its parameter, thus extracting its type. The big problem traditionally now is how to get
	that type out of the vartypeID() instance, and here's how we do it:
		1. unique_type_id() returns a monotonically increasing integer for every unique type
		   passed to it during this compilation unit. It also specialises an instance of
		   msvc_extract_type<unique_type_id, type>::id2type_impl<true>.
		2. vartypeID() returns a sized<unique_type_id> for the type where
		   sizeof(sized<unique_type_id>)==unique_type_id. We vector through sized as a means
		   of returning the unique_type_id at compile time rather than runtime.
		3. msvc_extract_type<unique_type_id> then extracts the type by using a bug in MSVC to
		   reselect the specialised child type (id2type_impl<true>) from within the specialisation
		   of itself originally performed by the above instance of unique_type_id. This bug works
		   because when MSVC calculated the signature of the specialised
		   msvc_extract_type<unique_type_id, type>::id2type_impl<true>, it does not include the
		   value of type in the signature of id2type_impl<true>. Therefore when we reselect
		   msvc_extract_type<unique_type_id>::id2type_impl<true> it erroneously returns the one
		   already in its list of instantiated types rather than correctly generating a newly
		   specialised msvc_extract_type<unique_type_id, msvc_extract_type_default_param>::id2type_impl<true>

	This bug allows the impossible and gives us a working typeof() in MSVC. Hopefully Microsoft
	won't fix this bug until they implement a native typeof.
	*/

	struct msvc_extract_type_default_param {};
	template<int ID, typename T = msvc_extract_type_default_param> struct msvc_extract_type;

	template<int ID> struct msvc_extract_type<ID, msvc_extract_type_default_param> {
		template<bool> struct id2type_impl; 
		typedef id2type_impl<true> id2type; 
	};

	template<int ID, typename T> struct msvc_extract_type 
    : msvc_extract_type<ID, msvc_extract_type_default_param>  { 
		template<> struct id2type_impl<true> //VC8.0 specific bugfeature 
		{ 
			typedef T type; 
		}; 
		template<bool> struct id2type_impl; 

		typedef id2type_impl<true> id2type; 
	}; 


	template<int N> class CCounter;

	// TUnused is required to force compiler to recompile CCountOf class
	template<typename TUnused, int NTested = 0> struct CCountOf {
		enum {
			__if_exists(CCounter<NTested>) { count = CCountOf<TUnused, NTested + 1>::count }
			__if_not_exists(CCounter<NTested>) { count = NTested }
		};
	};

	template<class TTypeReg, class TUnused, int NValue> struct CProvideCounterValue { enum { value = NValue }; };

	// type_id
	#define unique_type_id(type) \
		(CProvideCounterValue< \
			/*register TYPE--ID*/ typename msvc_extract_type<CCountOf<type >::count, type>::id2type, \
			/*increment compile-time Counter*/ CCounter<CCountOf<type >::count>, \
			/*pass value of Counter*/CCountOf<type >::count \
		 >::value)

	// Lets type_id() be > than 0
	class __Increment_type_id { enum { value = unique_type_id(__Increment_type_id) }; };

	// vartypeID() returns a type with sizeof(type_id)
	template<int NSize>	class sized { char m_pad[NSize]; };
	template<typename T> typename sized<unique_type_id(T)> vartypeID(T&);
	template<typename T> typename sized<unique_type_id(const T)> vartypeID(const T&);
	template<typename T> typename sized<unique_type_id(volatile  T)> vartypeID(volatile T&);
	template<typename T> typename sized<unique_type_id(const volatile T)> vartypeID(const volatile T&);

}

#define CXXO_DECLTYPE(expression) \
msvc_typeof_impl::msvc_extract_type< \
    sizeof(msvc_typeof_impl::vartypeID( expression )) \
>::id2type::type

#endif

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































Deleted cxxomfort/cxxomfort/extras/auto.hpp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#ifndef CXXOMFORT_EXTRAS_AUTO_HPP
#define CXXOMFORT_EXTRAS_AUTO_HPP
/**
 * @file auto.hpp
 * @brief Implements new auto semantics in C++03 where compatible.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces defined in this header:
 *
 * * CXXO_DECLTYPE (where emulation is provided by the compiler)
 * * CXXO_AUTO (where emulation is provided by the compiler)
 * 
*/

/**
 * @def CXXO_DECLTYPE
 * @brief Obtains the type of an expression, equivalent to eg.: @c __typeof__ (C++03) or @c decltype (C++11).
 */
/**
 * @def CXXO_AUTO
 * @brief Creates a variable with type determined by the initializer expression, equivalent to eg.: @c auto (C++11).
 */

#include <cxxomfort/config.hpp>
#include <cxxomfort/base.hpp>

#if (defined(CXXOMFORT_NOTICES))
    #pragma message CXXO_NOTICE("enabled extras: 'auto' emulation")
#endif

//namespace cxxomfort {
//namespace extras {

#if ((CXXOMFORT_CXX_STD >= 2011) || (CXXO_COMPILER_SUPPORT_auto==1 && CXXO_COMPILER_SUPPORT_decltype==1))

	#if (defined(CXXOMFORT_NOTICES) && CXXOMFORT_NOTICES > 1)
		#pragma message CXXO_NOTICE("using c++11's definition of auto")
	#endif
	#define CXXOMFORT_USING_auto
	#define CXXO_AUTO(var,expr) auto var ( expr )
	#define CXXO_AUTO_REF(var,expr) auto& var = expr
	#define CXXO_AUTO_CREF(var,expr) auto const& var (expr)
	#define CXXO_DECLTYPE(expr) decltype (expr)
	#define CXXO_TYPEOF(expr) __typeof__ (expr)

#else
// Not in C++11 mode

	#if defined (CXXOMFORT_NOTICES)
		#pragma message CXXO_NOTICE("enabled auto/decltype helpers")
	#endif

	#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC && CXXOMFORT_COMPILER_VERSION >= 300) \
	 || (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_CLANG)

		#define CXXOMFORT_USING_auto
		#define CXXO_AUTO(var,expr) __typeof__(expr) var (expr)
		#define CXXO_AUTO_CREF(var,expr) __typeof__(expr) const& var ( expr )
		#define CXXO_DECLTYPE(expr) __typeof__(expr)
		#define CXXO_TYPEOF(expr) __typeof__(expr)


	#elif (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_MSC && CXXOMFORT_COMPILER_VERSION >= 150)
		#define CXXOMFORT_USING_auto
		#include "auto-impl.hpp"
		#define CXXO_AUTO(var,expr) CXXO_DECLTYPE(expr) var ( expr )

	#else // no valid compiler found
		#error " cxxomfort library -- error: compiler doesn't support '__typeof__' or equiv."
	#endif // compiler test

#endif // no CXX11 support

//} //cxxomfort::extras
//} //cxxomfort

#endif // CXXOMFORT_EXTRAS_LOCALFN_HPP

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































Deleted cxxomfort/cxxomfort/extras/dynarray.hpp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#ifndef CXXOMFORT_EXTRAS_DYNARRAY_HPP
#define CXXOMFORT_EXTRAS_DYNARRAY_HPP
/**
 * @file cxxomfort/extras/dynarray.hpp
 * @brief Implementation of n2648 "C++ Dynamic Arrays" proposal, "dynarray" component
 * @author Luis Machuca Bezzaza
 * 
 * "dynarray" is a proposal for a container of contiguous elements where 
 * the container size is fixed at construction time - in a way similar to 
 * std::array<> except the size is specified at runtime - and where 
 * storage of the elements can be handled *at the stack* at the discretion 
 * of the compiler (which requires toolkit support).
 * 
 * The implementation here disregards the facet of stack-based allocation 
 * (which is not practically available in C++03/11 anyway) and instead 
 * focuses on the facet of the ever-missing from the C++ standard toolkit's 
 * "fixed vector" / "dynamic array" container requirement.
 * 
 */


// To invoke this via a std header see cstd/dynarray.

// TBD: implement option to have dynarray be copy assignable

#include <cxxomfort/base.hpp>
#include <cxxomfort/library/sequences.hpp> // is_iterator
#include <iterator>
#include <algorithm>
#include <stdexcept>
#include <memory>
#define CXXOMFORT_IMPLEMENTS_n2648 CXXO_LIBRARY()
#define CXXOMFORT_IMPLEMENTS_dynarray CXXOMFORT_IMPLEMENTS_n2648


//
// using dynarray
//
#if (defined(CXXOMFORT_NOTICES))
    #pragma message CXXO_NOTICE("enabled extras: dynarray<T> implementation")
#endif


#if (CXXOMFORT_CXX_STD >= 2011)
    //#define CXXO_NOEXCEPT CXXO_NOEXCEPT
    #define INIT_LIST(T) std::initializer_list<T> const&
    #define _DELETED_ =delete
#else
    #define _DELETED_ 
#endif

namespace cxxomfort{
namespace extras{
namespace dynarray{

template <typename T> class dynarray;

/**
 * @brief Dynamic array (aka fixed vector) container for C++ from n2648 ("C++ Dynamic Arrays") by Lawrence Crowl
 * @anchor dynarray
 * @ingroup extra-features
 * @sa n2648
 * 
 * A @c dynarray is a container of contiguous storage of elements 
 * of type @e T for which the storage of the elements can be handled 
 * at the stack at the discretion of the compiler. 
 * It behaves much like a <code>vector<T></code> except there is no resize or 
 * reserve support - the size of the container is fixed at construction time.
 * 
 * <b>From n2648</b>:
 * 
 * "The header <dynarray> defines a class template for storing sequences 
 * of objects where the size is fixed at construction. 
 * A dynarray supports random access iterators. 
 * An instance of dynarray<T> stores elements of type T. 
 * The elements of a dynarray are stored contiguously, meaning that if d 
 * is an dynarray<T> then it obeys the identity 
 * &a[n] == &a[0] + n for all 0 <= n < N."
 * 
 *
 * 
 * A @c dynarray  presents the some of the same interface convenients as 
 * other standard containers:
 * 
 * * except where specified, no members throw
 * * copy constructor and iterator constructor
 * * indexed accesors (@c at() and @c operator[] ) with usual semantics
 * * iteration member accesors and types
 * * nonmember equality comparison operators
 * 
 * This implementation is slightly different than the one in n2648 
 * while retaining the same functionality.
 * 
 * Key differences:
 * 
 * * no support for stack-allocation - this implementation focuses on 
 * the lack of a "fixed vector" container type in the Standard.
 * * cxxomfort's @c dynarray is move-constructible
 *  (but -very importantly- not move-assignable!).
 * 
 * To invoke this in a standard manner, the header @c <dynarray> is 
 * provided in cstd/experimental directory.
 * 
 */
template <typename T> class dynarray {
    typedef dynarray<T>  this_type;

    public:
    typedef T            value_type;         ///< type of contained value
    typedef size_t       size_type;
    typedef ptrdiff_t    difference_type;
    typedef value_type&       reference;
    typedef value_type const& const_reference;
    typedef value_type*       pointer;
    typedef const value_type* const_pointer;
    // see if those should be changed to checked iterators?
    typedef T*           iterator;           ///< @c iterator type
    typedef T const*     const_iterator;     ///< @c const_iterator type
    typedef std::reverse_iterator<iterator> reverse_iterator;
    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

    public:

    explicit dynarray (size_type N);     ///< (1) count-constructor
    dynarray (size_type N, T const& v);  ///< (3) count-constructor
    dynarray (dynarray const &V);        ///< (5) copy-constructor
    /// iterator-constructor
    template <typename It>
    dynarray (It ini, It fin, typename std::enable_if<is_iterator<It>::value,bool>::type* = nullptr);
    
    ////! Inicializa un vector de una lista estática en C++11
#if (CXXOMFORT_CXX_STD >= 2011) || defined(DOXYGEN_DOC)
    dynarray (std::initializer_list<T> const&) CXXO_NOEXCEPT;             ///< (7) initializer_list-ctor
#endif

    dynarray (CXXO_RV_REF(dynarray) p) CXXO_NOEXCEPT;  ///< move-constructor

    ~dynarray ();                                 ///< destructor

    size_type       max_size () const CXXO_NOEXCEPT { return std::numeric_limits<size_t>::max(); }
    //! size of container (fixed value)
    size_type       size () const CXXO_NOEXCEPT { return m_sz; } // nothrow
    bool            empty () const CXXO_NOEXCEPT { return m_p == nullptr && m_sz == 0; } // nothrow

    //! access of storage buffer
    const T*        data () const CXXO_NOEXCEPT { return m_p; } // nothrow
    T*              data () CXXO_NOEXCEPT { return m_p; } // nothrow

    //! checked access to element at index @em idx
    const_reference at (size_t idx) const {
        if (m_sz <= idx) throw std::out_of_range("dynarray at(size_t) const");
        return m_p[idx];
    }
    //! @overload at
    reference at (size_t idx) {
        if (m_sz <= idx) throw std::out_of_range("dynarray at(size_t)");
        return m_p[idx];
    }

    //! direct access to element at index @em idx
    const_reference operator[] (size_t idx) const CXXO_NOEXCEPT { // nothrow
        return m_p[idx];
    }
    //! @overload operator[]
    reference operator[] (size_t idx) CXXO_NOEXCEPT { // nothrow
        return m_p[idx];
    }

    const_reference front () const { return m_p[0]; } // nothrow
    reference       front () { return m_p[0]; } // nothrow
    const_reference back  () const { return m_p[m_sz-1]; } // nothrow
    reference       back () { return m_p[m_sz-1]; } // nothrow

    //@ Iterator to the beginning
    const_iterator  cbegin () const CXXO_NOEXCEPT { return m_p; } // nothrow
    //@ Iterator to the beginning
    const_iterator  begin () const CXXO_NOEXCEPT { return cbegin(); } // nothrow
    //@ @overload begin
    iterator        begin () CXXO_NOEXCEPT { return m_p; } // nothrow
    const_iterator  cend () const CXXO_NOEXCEPT { return m_p+m_sz; } // nothrow
    //@ Iterador apuntando al final+1.
    const_iterator  end () const CXXO_NOEXCEPT { return cend(); } // nothrow
    //* @overload end
    iterator        end   () CXXO_NOEXCEPT { return m_p+m_sz; } // nothrow

    const_reverse_iterator     rbegin () const CXXO_NOEXCEPT {
        return const_reverse_iterator(this->end());
    }
    reverse_iterator     rbegin () CXXO_NOEXCEPT {
        return reverse_iterator(this->end());
    }
    const_reverse_iterator     rend () const CXXO_NOEXCEPT {
        return const_reverse_iterator(this->begin());
    }
    reverse_iterator     rend () CXXO_NOEXCEPT {
        return reverse_iterator(this->begin());
    }

    void fill (T const& v) CXXO_NOEXCEPT {
        for (iterator i= this->begin(); i != this->end(); ++i) {*i= v;}
    }

    private:
    size_t m_sz;
    T* m_p;

    // Move Interface
    private:
    CXXO_COPYABLE_MOVABLE_NONASSIGNABLE (dynarray);

    T* alloc (size_type n) {
        return reinterpret_cast<T*>( new char [n * sizeof(T)] );
    }

    private:
    dynarray ()          _DELETED_ ;    //< non-default-constructible
    //dynarray& operator= (dynarray const&) _DELETED_ ;    //< non-assignable

};

// Copy Constructor
template <typename T>
dynarray<T>::dynarray (dynarray const &V) // strong_throw
: m_p ( alloc(V.m_sz) ), m_sz(V.m_sz) {
    try {
        using namespace std;
        uninitialized_copy(V.begin(), V.end(), this->begin());
    } catch(...) {
        delete[] m_p; m_p= nullptr;
        throw; // rethrow
    }// ~catch
}


// Constructor cantidad (N)
template <typename T>
dynarray<T>::dynarray (size_type N) // strong_throw
: m_sz(N), m_p ( alloc(N) ) {
    size_t i;
    try {
        using namespace std;
        uninitialized_fill(m_p, m_p+m_sz, T());
    } catch(...) {
        for (; i > 0 ; --i) (m_p+i-1)->~T();
        m_sz= 0;
        throw; // rethrow
    }//~catch
}

template <typename T>
dynarray<T>::dynarray (size_type N, T const& v) // strong_throw
: m_sz(N), m_p ( alloc(N) ) {
    using namespace std;
    size_t i= 0;
    try {
        for (i=0; i < m_sz; ++i) ::new (m_p+i) T(v);
        //uninitialized_fill(m_p, m_p+m_sz, v);
    } catch(...) {
        for (; i > 0 ; --i) (m_p+i-1)->~T();
        m_sz= 0;
        throw; // rethrow
    }//~catch
}


// This assumes none of the involved constructors will throw!
template <typename T>
template <typename It>
dynarray<T>::dynarray (It ini, It fin, typename std::enable_if<is_iterator<It>::value,bool>::type*) 
:  m_sz ( std::distance(ini, fin) ), m_p (alloc(m_sz)) {
    using namespace std;
    try {
        //m_p= alloc(m_sz);
        uninitialized_copy(ini, fin, m_p);
    } catch (...) {
        delete[] m_p; m_p= nullptr;
        throw;
    }
}

#if (CXXOMFORT_CXX_STD >= 2011)
// This assumes none of the involved constructors will throw!
template <typename T>
dynarray<T>::dynarray (std::initializer_list<T> const& L) CXXO_NOEXCEPT // shouldnt_throw
: m_p ( alloc(std::distance(L.begin(),L.end())) ), m_sz( std::distance(L.begin(),L.end()) ) {
    std::uninitialized_copy(L.begin(), L.end(), m_p);
}
#endif

// Move constructor
template <typename T>
dynarray<T>::dynarray (CXXO_RV_REF( dynarray ) p)  CXXO_NOEXCEPT // shouldnt_throw
: m_p(p.m_p), m_sz(p.m_sz) {
    p.m_p= nullptr;
    p.m_sz= 0;
}


// Destructor
template <typename T>
dynarray<T>::~dynarray () { 
    using namespace std;
    typedef typename conditional < std::is_const<T>::value , 
        char const*,
        char*>
    ::type buffertype;
    for (size_t i=0; i < m_sz; ++i) {
        (m_p+i)->~T();
    }
    delete[] reinterpret_cast<buffertype>(m_p); 
    m_p= nullptr;
}

template <typename T>
inline bool operator== (dynarray<T> const& a, dynarray<T> const& b) {
    return ( a.size() == b.size() ) && std::equal(a.begin(), a.end(), b.begin()) ;
}

template <typename T>
inline bool operator!= (dynarray<T> const& a, dynarray<T> const& b) {
    return !(a==b);
}

#if (CXXOMFORT_CXX_STD >= 2011)
#undef INIT_LIST
#else
#endif
#undef _DELETED_

}//~dynarray
}//~extras
}//~cxxomfort

/**
 * @class dynarray
 * @brief Dynamic array template class from C++14/2y (using @ref dynarray )
 */

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































Deleted cxxomfort/cxxomfort/extras/foreach.hpp.

1
2
3
#include <cxxomfort/base.hpp>
#pragma message CXXO_WARNING("deprecated header. New header is <cxxomfort/library/foreach.hpp>")
#include <cxxomfort/library/foreach.hpp>
<
<
<






Deleted cxxomfort/cxxomfort/extras/forward_list.hpp.

1
2
3
#include <cxxomfort/base.hpp>
#pragma message CXXO_WARNING("deprecated header. New header is <cxxomfort/forward_list.hpp>")
#include <cxxomfort/forward_list.hpp>
<
<
<






Deleted cxxomfort/cxxomfort/extras/optional-impl.hpp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
#ifndef CXXOMFORT_EXTRAS_OPTIONAL_IMPL_HPP
#define CXXOMFORT_EXTRAS_OPTIONAL_IMPL_HPP
/**
 * @file cxxomfort/extras/optional-impl.hpp
 * @brief Implementation details of <code>optional<T></code> proposal.
 */

/*
 * Header file with implementation of optional
 * This is directly loaded from optional.hpp
 * as such we are already within namespace cxxomfort::extras::optional::
 */

namespace detail {

using std::aligned_storage;

CXXOMFORT_CXX11_CODE(constexpr,const) struct trivial_init_t {} trivial_init = {};

/* storage of the optional contents as an aligned_storage */
template <typename T>
struct storage_align_t {
    typename aligned_storage<sizeof(T),alignof(T)>::type buff_;

    void const * address () const { return std::addressof(/*dummy.*/buff_); }
    void       * address ()       { return std::addressof(/*dummy.*/buff_); }

    // "disengaged" constructor
    CXXO_CONSTEXPR storage_align_t (trivial_init_t) CXXO_NOEXCEPT : /*dummy()*/ buff_() {}
    ~storage_align_t () {}
};

/* constexpr-storage for C++11 optionals where T is a fundamental */
/* TODO: implement optional<fundamental_T> with this storage and 
 * constexpr constructors to make it a literal type
 */
#if (CXXOMFORT_CXX_STD >= 2011 || (CXXOMFORT_CXX_EMULATION>=2011 && CXXO_COMPILER_SUPPORT_constexpr>0 ))
template <typename T>
union storage_constexpr11_t {
    unsigned char dummy_;
    T value_;

    constexpr storage_constexpr11_t ( trivial_init_t ) noexcept : dummy_() {};
    ~storage_constexpr11_t () = default;
};

#endif


}

#if 1

namespace detail {

// Wrapper for nullable types
template <typename T, typename=void>
class optional_impl {
    static_assert (!std::is_lvalue_reference<T>::value, "optional<T>: T must not be a reference type");
    static_assert ((!std::is_same<T,nullopt_t>::value), "optional<T>: T must not be an optional 'nullopt' tag");
    

    private:
    typedef detail::storage_align_t<T> storage_type;
    public:
    typedef T  value_type;
    static const bool is_specialized = false;
    
    //! Default constructor (@c noexcept ; trivial if @p T is a fundamental type)
    CXXO_CONSTEXPR optional_impl () CXXO_NOEXCEPTNOTHROW 
    : _engaged(false), _storage(detail::trivial_init) {}

    //! Copy constructor (defaulted-trivial if @p T is a fundamental type)
    optional_impl (optional_impl const& ot)
    : _storage(detail::trivial_init), _engaged(ot._engaged) {
        if (_engaged) new (std::addressof(_storage)) value_type(reinterpret_cast<T const&>(ot._storage)) ;
    }

    //! Disengaged state constructor (@c constexpr  @c noexcept )
    CXXO_CONSTEXPR optional_impl (nullopt_t) CXXO_NOEXCEPTNOTHROW
    : _storage(detail::trivial_init), _engaged(false) {}

    //! Engaged state constructor
    explicit optional_impl (T const& t)
    : _storage(detail::trivial_init), _engaged(true) {
        new (std::addressof(_storage)) value_type(t);
    }

#if (CXXOMFORT_CXX_STD >= 2011)
    //! Emplace constructor 
    template <typename... Args>
    optional_impl (in_place_t, Args&&... args)
    : _engaged(true), _storage(detail::trivial_init) {
        new (std::addressof(_storage)) value_type(std::forward<Args>(args)...);
    }
#else

    //! emplace constructor
    optional_impl (in_place_t)
    : _engaged(true), _storage(detail::trivial_init) {
        new (std::addressof(_storage)) value_type() ;
    }

    //! emplace constructor
    template <typename A1>
    optional_impl (in_place_t, CXXO_FWD_REF(A1) a1)
    : _engaged(true), _storage(detail::trivial_init) {
        new (std::addressof(_storage)) value_type(a1) ;
    }
    //! emplace constructor
    template <typename A1, typename A2>
    optional_impl (in_place_t, CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2)
    : _engaged(true), _storage(detail::trivial_init) {
        new (std::addressof(_storage)) value_type(a1,a2) ;
    }
    //! emplace constructor
    template <typename A1, typename A2, typename A3>
    optional_impl (in_place_t, CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2, CXXO_FWD_REF(A3) a3)
    : _engaged(true), _storage(detail::trivial_init) {
        new (std::addressof(_storage)) value_type(a1,a2,a3) ;
    }
    //! emplace constructor
    template <typename A1, typename A2, typename A3, typename A4>
    optional_impl (in_place_t, CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2, CXXO_FWD_REF(A3) a3, CXXO_FWD_REF(A4) a4)
    : _engaged(true), _storage(detail::trivial_init) {
        new (std::addressof(_storage)) value_type(a1,a2,a3,a4) ;
    }
#endif

    //! Destructor (trivial if @p T is a fundamental type)
    ~optional_impl () { this->destruct(); }


    //! Assignment (@c noexcept  and trivial if @p T is a fundamental type)
    optional_impl& operator= (optional_impl const& ot) {
        if (_engaged && ot._engaged) *cast_it()= *ot.cast_it();
        else if (_engaged && !ot._engaged) *this= nullopt;
        else if (!_engaged && ot._engaged) *this= *ot.cast_it();
        return *this;
    }
    //! Disengaging assignment (trivial if @p T is a fundamental type)
    optional_impl& operator= (nullopt_t) CXXO_NOEXCEPT {
        destruct();
        _engaged= false;
        return *this;
    }
    //! Engaging assignment (trivial if @p T is a fundamental type)
    optional_impl& operator= (T const& t) {
        if (!_engaged) {
            new (std::addressof(_storage)) value_type(t);
            _engaged= true;
        }
        return *this;
    }

    CXXO_CONSTEXPR CXXO_EXPLICIT_OPERATOR(bool) () const CXXO_NOEXCEPT {
        return engaged();
    }


    //! Obtain value of a @b engaged  object.
    T const&        value () const {
        if (!_engaged) throw bad_optional_access("disengaged call to value() const");
        return *cast_it();
    }
    //! @overload value
    T&              value () {
        if (!_engaged) throw bad_optional_access("disengaged call to value() non-const");
        return *cast_it();
    }

    T     value_or (T const& alt) const CXXO_NOEXCEPT {
        if (!_engaged) return alt;
        else return *cast_it();
    }

    //! Check engagement state of object.
    CXXO_CONSTEXPR bool  engaged () const CXXO_NOEXCEPT { return _engaged; }

    //! Obtain value of an @v engaged  object.
    CXXO_CONSTEXPR const T&   operator* () const CXXO_NOEXCEPT { return value(); }
    //! @overload operator*
    T&         operator* () { return value(); }

    CXXO_CONSTEXPR T const* operator-> () const CXXO_NOEXCEPT {
        return cast_it();
    }
    T* operator-> () {
        return cast_it();
    }


    //! Swap contents with another object.
    void swap (optional_impl& rhs) CXXO_NOEXCEPT {
        if (!_engaged && !rhs._engaged) return;
        else if (_engaged && !rhs._engaged) { rhs= *this; *this= nullopt; }
        else if (!_engaged && rhs._engaged) { *this= rhs; rhs= nullopt; }
        else {
            using std::swap;
            swap(*cast_it(), *rhs.cast_it());
        }
        
    }

#if (CXXOMFORT_CXX_STD >= 2011)
    template <typename... Args>
    void emplace (Args&&... args) {
        *this= nullopt;
        *this= value_type(std::forward<Args>(args)...);
    }
    
#else
    #if 0
    void emplace () {
        this->assign(nullopt);
        this->initialize();
    }
    template <typename A1>
    void emplace (CXXO_FWD_REF(A1) a1) {
        this->assign(nullopt);
        this->initialize(std::forward<A1>(a1));
    }

    template <typename A1, typename A2>
    void emplace (CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2) {
        this->assign(nullopt);
        this->initialize(std::forward<A1>(a1), std::forward<A2>(a2));
    }

    template <typename A1, typename A2, typename A3>
    void emplace (CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2, CXXO_FWD_REF(A3) a3) {
        this->assign(nullopt);
        this->initialize(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3));
    }
    #endif
#endif


    private:
#pragma pack(push,2)
    storage_type    _storage;
    bool            _engaged;
#pragma pack(pop)
    value_type*          cast_it () {
        return reinterpret_cast<value_type*> (std::addressof(_storage));
    }
    value_type const*    cast_it () const {
        return reinterpret_cast<value_type const*> (std::addressof(_storage));
    }
    void destruct () {
        if (_engaged) cast_it()->~value_type();
    }


};

#endif


#if 1
//
// The implementation of an optional<T> for fundamental types T 
// is fairly simple and can be completely done inplace
// This implementation allows it to be trivially copy-constructible, 
// copy-assignable and destructible, as well as 
// constexpr-constructible in C++11.
//
template <typename T>
class optional_impl<T, typename std::enable_if<std::is_fundamental<T>::value>::type > {
    private:
    typedef T       storage_type;
    protected:
    typedef T       value_type;
    typedef optional<T>  optional_type;
    static const bool is_specialized = true;

    CXXO_CONSTEXPR optional_impl () CXXO_NOEXCEPT
    : _engaged(false) {}
    // trivially copyable
#if (CXXOMFORT_CXX_STD >= 2011)
    constexpr optional_impl (optional_impl const&) noexcept = default;
#else
    optional_impl (optional_impl const& r) CXXO_NOEXCEPT
    : _engaged(r._engaged), _storage(r._storage) {}
#endif
    CXXO_CONSTEXPR optional_impl (nullopt_t) CXXO_NOEXCEPT
    : _engaged(false) {}
    CXXO_CONSTEXPR explicit optional_impl (T t) CXXO_NOEXCEPT
    : _engaged(true), _storage(t) {}
    // trivially destructible
    CXXOMFORT_CXX11_CODE(~optional_impl() = default,);
    
    CXXO_CONSTEXPR bool engaged () const CXXO_NOEXCEPT { return _engaged; }
    
    CXXO_CONSTEXPR CXXO_EXPLICIT_OPERATOR(bool) () const CXXO_NOEXCEPT {
        return _engaged;
    }
    
    // trivially copy-assignable
#if (CXXOMFORT_CXX_STD >= 2011)
    optional_impl& operator= (optional_impl const&) CXXO_NOEXCEPT = default;
#else
    optional_impl& operator= (optional_impl const& r) CXXO_NOEXCEPT {
        _engaged= r._engaged;
        _storage= r._storage;
        return *this;
    }
#endif

    optional_impl& operator= (nullopt_t) CXXO_NOEXCEPT {
        _engaged=false;
        return *this;
    }
    optional_impl& operator= (T t) CXXO_NOEXCEPT {
        _engaged= true;
        _storage= t;
        return *this;
    }
    
    CXXO_CONSTEXPR T const& operator* () const CXXO_NOEXCEPT {
        return _storage;
    }
    
    T& operator* () CXXO_NOEXCEPT {
        return _storage;
    }
    
    T const* operator-> () const CXXO_NOEXCEPT {
        return std::addressof(_storage);
    }
    T* operator-> () CXXO_NOEXCEPT {
        return std::addressof(_storage);
    }
    
    T const& value () const {
        if (_engaged) return _storage; else throw bad_optional_access("call to value() const");
    }
    
    T& value () {
        if (_engaged) return _storage; else throw bad_optional_access("call to value() non-const");
    }

    T value_or (T alt) const CXXO_NOEXCEPT { return (_engaged ? _storage : alt); }

    // emplace constructions can only take one argument
    void emplace (T t) CXXO_NOEXCEPT {
        (*this= t);
    }
    void emplace (...) {
        static_assert( std::is_compound<T>::value, "optional::emplace over a fundamental type does not take more than one argument");
    }
    
    void swap (optional_impl& o) CXXO_NOEXCEPT {
        using std::swap;
        std::swap(_engaged, o._engaged);
        std::swap(_storage, o._storage);
    }
    
    private:
#pragma pack(push,2)
    bool            _engaged;
    T               _storage;
#pragma pack(pop)
};
#endif

// detail
}

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































Deleted cxxomfort/cxxomfort/extras/optional-io.hpp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#ifndef CXXOMFORT_EXTRAS_OPTIONAL_IO_HPP
#define CXXOMFORT_EXTRAS_OPTIONAL_IO_HPP

#include <cxxomfort/extras/optional.hpp>
#include <string>
#include <sstream>
#include <iostream>

namespace cxxomfort {
namespace extras {
namespace optional {

struct io_optional_empty {
    public:
    static std::string& value() {
        static std::string v= "{}";
        return v;
    }
};

template <typename T>
std::istream& operator>> (std::istream& is, optional<T>& o) {
    std::string s;
    if (is>> s) {
        if (s == io_optional_empty::value()) {
            o= optional<T>();
        } else {
            // try to convert via a stringstream
            std::stringstream f(s);
            T t;
            if (f>> t) {
                o= t;
            } else {
                is.clear (std::ios::failbit);
            }
        }
    }
    return is;
}

template <typename T>
std::ostream& operator<< (std::ostream& os, optional<T> const& o) {
    os<< o.value_or(io_optional_empty::value());
    return os;
}

}
}
}


#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































Deleted cxxomfort/cxxomfort/extras/optional.hpp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#ifndef CXXOMFORT_EXTRAS_OPTIONAL_HPP
#define CXXOMFORT_EXTRAS_OPTIONAL_HPP
/*
 *
 * Optional as per C++ Proposal (n1878):
 * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1878.htm
 * Also incorporates some implementation details and fixes from n3527
 * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3527.html
 *
 */
#include <cxxomfort/config.hpp>
#include <cxxomfort/base.hpp>
#include "../base/explicit_cast.hpp"
#include <type_traits>
#include <cassert>
#include <stdexcept>
#include <iostream>

#if defined(CXXOMFORT_NOTICES)
    #pragma message CXXO_NOTICE("enabled extras: optional<T> implementation from experimental")
#endif

namespace cxxomfort {
namespace extras {
namespace optional {

/**
 * @class cxxomfort::extras::optional::optional
 * @brief Wrapper for Nullable, Regularized types
 * @ingroup extra-features
 * @anchor optional
 *
 * @c optional is a nullable-type wrapper for type @e T - it can store
 * a value of type T or "nothing" (indicated by @c 'nullopt').
 * It is indirectly convertible to <code>T const&</code>
 * and provides pointer-like access interface semantics.
 *
 * Differences with the C++14 proposal:
 *
 * * (TBD)
 *
 * Implementation specifics:
 *
 * <ul><li>Support for @c alignof  and @c aligned_storage are required in C++03 mode.
 * </li><li>If @p T is a fundamental type, @c optional<T>  is :
 * * In C++03, trivially copyable, trivially assignable
 * and trivially destructible.
 * * In C++11, besides the above, a "literal type", and all the
 * constructors are @c noexcept(true) .
 * </li></ul>
 *
 * @sa n1878, n3527
**/
template <typename T> class optional;
//template <typename T, typename Enabler=void> class optional;

/*
struct nullopt_t {
  struct init{};
  CXXOMFORT_CXX11_CODE(constexpr,) nullopt_t(init){};
};
*/


//! disengaged-state tag indicator for @c optional
CXXOMFORT_CXX11_CODE(constexpr,const) struct nullopt_t {
    // added in c++17
    CXXO_CONSTEXPR explicit nullopt_t (int) CXXO_NOEXCEPT {}
} nullopt (3);

//! emplace-construction tag indicator for @c optional
CXXOMFORT_CXX11_CODE(constexpr,const) struct in_place_t{} in_place = {};


//! bad access exception for @c optional
class bad_optional_access : public std::logic_error {
    public:
    explicit bad_optional_access(const std::string& what_arg) : std::logic_error(what_arg) {}
    explicit bad_optional_access(const char* what_arg) : std::logic_error(what_arg) {}
};

//! Trait identifying optional types
template <typename T> struct is_optional;

/*
 * Declaration of nonmember functions
 */
//! equality comparison
template<typename T> inline CXXO_CONSTEXPR bool operator== (optional<T> const&, optional<T> const&);
template<typename T> inline CXXO_CONSTEXPR bool operator!= (optional<T> const&, optional<T> const&);
//! get the value of an @b engaged optional
template<typename T> inline T const& get ( optional<T> const& opt );
//! get the value of an @b engaged optional
template<typename T> inline T&       get ( optional<T> & opt );
//! get a pointer to value of an optional, or @c nullptr if disengaged
template<typename T> inline T const* get ( optional<T> const* opt );
//! get a pointer to value of an optional, or @c nullptr if disengaged
template<typename T> inline T*       get ( optional<T>* opt );
//! get a pointer to value of an optional, or @c nullptr if disengaged
template<typename T> inline T const* get_pointer ( optional<T> const& opt );
//! get a pointer to value of an optional, or @c nullptr if disengaged
template<typename T> inline T*       get_pointer ( optional<T> & opt );
//! global swap
template<typename T> inline void swap( optional<T>& x, optional<T>& y ) ;

//
// implementation is loaded here separately,
// might change between c++11 and c++03
//

#include "optional-impl.hpp"

// ----

/**
 * @brief Trait that identifies a @c optional  type.
 * */
template <typename T> struct is_optional
: public std::false_type {};

template <typename T> struct is_optional< optional<T> >
: public std::true_type {};


//
// central interface for optional
//
template <typename T>
class optional
: public detail::optional_impl<T> {
    private:
    typedef detail::optional_impl<T> base_type;
    public:
    typedef T value_type;


    CXXO_CONSTEXPR optional () CXXO_NOEXCEPT : base_type() {};
    CXXO_CONSTEXPR optional (optional const& p) : base_type(p) {};
    CXXO_CONSTEXPR optional (T const& v) CXXO_NOEXCEPT : base_type(v) {};
    CXXO_CONSTEXPR optional (nullopt_t) CXXO_NOEXCEPT : base_type(nullopt) {};

    template<typename A1>
    optional (in_place_t, CXXO_FWD_REF(A1) a1)
    : base_type(in_place, a1) {}
    template <typename A1, typename A2>
    optional (in_place_t, CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2)
    : base_type(in_place, std::forward<A1>(a1), std::forward<A2>(a2)) {}

    ~optional() {};


    //optional& operator= (optional const&) CXXO_NOEXCEPT;
#if (1 || CXXOMFORT_CXX_STD >= 2011)
    using base_type::operator= ;
#else
    optional& operator= (optional const& r) {
        ((base_type*)this)->operator= ((base_type&)(r));
        return *this;
    }
    optional& operator= (T const& r) {
        ((base_type*)this)->operator= (r);
        return *this;
    }
    optional& operator= (nullopt_t) CXXO_NOEXCEPT {
        ((base_type*)this)->operator= (nullopt);
        return *this;
    }
#endif

/* this should be inherited from impl */
/*
#if (CXXOMFORT_CXX_STD >= 2011)
    using base_type::operator bool;
#else
    using base_type::CXXO_EXPLICIT_OPERATOR(bool);
#endif
*/

    // unchecked access

    using base_type::operator* ;
    using base_type::operator-> ;

    // checked access

    using base_type::value;
    using base_type::value_or;

    using base_type::swap;
    //void swap (optional& b) {
    //    ((base_type*)this)->swap( (base_type&)(b) );
    //}

    using base_type::is_specialized;

};

//
// nonmember get
//

//! nonmember 'get'
template <typename T>
inline T const* get_ptr (optional<T> const& o) { return o.operator->(); }
//! nonmember 'get'
template <typename T>
inline T const& get (optional<T> const& o) { return o.operator*(); }
//! nonmember 'get'
template <typename T>
inline T& get (optional<T>& o) { return o.operator*(); }


template <typename T> inline
T* get (optional<T>* po) {
    return (*po == nullopt) ? nullptr : po->operator->();
}

template <typename T> inline
T const* get (optional<T> const* po) {
    return (*po == nullopt) ? nullptr : po->operator->();
}

//! global swap
template <typename T>
inline void swap (optional<T>& a, optional<T>& b) {
    a.swap(b);
}


//! utility typedef for an <code>optional<signed int></code>.
typedef optional<signed int> opt_int_t;
//! utility typedef for an <code>optional<unsigned int></code>.
typedef optional<unsigned int> opt_uint_t;


#if (CXXOMFORT_CXX_STD >= 2011)

#endif


} // optional::
} // extras::
} // cxxomfort::


/*
// Maps hash< optional<T> > with the same semantics as hash<T>
// requires <functional> to be included
// #include <functional>
namespace std {
#if (!defined(CXXOMFORT_CXX11_MODE) && CXXOMFORT_CXX11_EMULATION==0)
namespace tr1 {
#endif

template <typename T> struct hash< ::cxxomfort::extras::optional::optional<T> >
: protected hash<T> {
    private:
    typedef hash<T> base_t;
    public:
    typename hash<T>::result_type operator() (::cxxomfort::extras::optional::optional<T> const& ot) const {
        using namespace cxxomfort::extras::optional;
        if (ot != nullopt) {
            std::cerr<< "[hash<optional> with engaged var]"<< std::endl;
            T const& t (*ot);
            return static_cast< base_t const* >(this)->operator()(t);
        } else return hash<T*>()(0);
    }

};

#if (!defined(CXXOMFORT_CXX11_MODE) && CXXOMFORT_CXX11_EMULATION==0)
}
#endif
}
*/

#endif

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<