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

Overview
Comment:Commit 2017-08-11 - Emulation detection fixes (c++0x, c++1y).
  • cxxomfort: Implement a listing of CXXOMFORT_IMPLEMENTS_nxxxx macros.
  • cxxomfort: General fixes to ensure GCC 4.6 compatibility.
  • cxxomfort: Improvements to detection of "c++1y" support (__cplusplus == 2013 or similar).
  • algorithm: Correction to transform_inplace (wrong typename).
  • algorithm: Fixed detection of all_of algorithms in C++0x emulation mode.
  • functional: move functional's fixes for MSVC C++03 to its own header.
  • memory: Fixed detection of required backports in MSVC 2010 (which provides __alignof but doesn't announce it).
  • string: Fixed detection of required backports in MSVC 2010 (which provides a borked to_string).
  • string: Added r_trim, l_trim, trim generics for basic_strings.
  • type_traits: Fixed detection of common_type support.
  • utility: Fixed detection of declval support.
  • extras: Added observer_ptr proposal (n3840).
  • extras: Reimplemented extras::optional, more in line with std::experimental proposal status.
  • tags: Added tags for some free functions made available.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ef968a6c784813955cdc0114a47c17adf5fd3616
User & Date: luismachuca 2017-08-11 18:12:29
Context
2017-12-19
03:32
Commit 2017-12-19 - Transparent headers and typesafe enum.
  • cxxomfort: Added cstddef.hpp and its transparent header mirror.
  • cxxomfort: Added random.hpp and its transparent header mirror.
  • cxxomfort: Corrected CXXOMFORT_NOTICES in various headers.
  • config: Improved detection of MSVC 2015 (ver 1900) C++ support.
  • config: Improved detection of C++17 mode.
  • library: Added typesafe_enum.
  • random: Renames of the functors in C++03 according to C++11.
  • PENDING: cstddef: Adding std::byte from C++17.
  • PENDING: functional: Fixes to functors, adding not_fn.
  • PENDING: in_place tag for experimental::optional.
  • PENDING: library: strsprintf.
check-in: d2fcaba9 user: luismachuca tags: trunk
2017-08-11
18:12
Commit 2017-08-11 - Emulation detection fixes (c++0x, c++1y).
  • cxxomfort: Implement a listing of CXXOMFORT_IMPLEMENTS_nxxxx macros.
  • cxxomfort: General fixes to ensure GCC 4.6 compatibility.
  • cxxomfort: Improvements to detection of "c++1y" support (__cplusplus == 2013 or similar).
  • algorithm: Correction to transform_inplace (wrong typename).
  • algorithm: Fixed detection of all_of algorithms in C++0x emulation mode.
  • functional: move functional's fixes for MSVC C++03 to its own header.
  • memory: Fixed detection of required backports in MSVC 2010 (which provides __alignof but doesn't announce it).
  • string: Fixed detection of required backports in MSVC 2010 (which provides a borked to_string).
  • string: Added r_trim, l_trim, trim generics for basic_strings.
  • type_traits: Fixed detection of common_type support.
  • utility: Fixed detection of declval support.
  • extras: Added observer_ptr proposal (n3840).
  • extras: Reimplemented extras::optional, more in line with std::experimental proposal status.
  • tags: Added tags for some free functions made available.
check-in: ef968a6c user: luismachuca tags: trunk
2017-07-30
16:55
Commit 2017-07-30 - Future version preparation; Library additions.
  • cxxomfort: Preparation for CXXOMFORT_VERSION to be deprecated in favor of CXXOMFORT_DATE.
  • cxxomfort: Added cxxomfort::output_info(Stream&).
  • library: fixed_vector is now def-ctible, swappable and assignable.
  • library: Added algorithmfn.hpp (algorithm helpers).
  • library: Added fundamental.hpp (object wrapper for ints and other fundamental types).
  • library: Added iteratorfn.hpp (iterator helpers).
  • algorithm: moved to its own namespace.
  • algorithm: Renamed the header to "algorithm.hpp" (the old header is still available).
  • algorithm: Added transform_n.
  • algorithm: Added transform_inplace.
  • algorithm: Added find_last_if.
  • functional: moved to its own namespace.
  • iterator: moved to its own namespace.
  • functional: transparent functors now inherit from std:: ones, enabling their use inside std::bind.
  • memory: moved aligned_storage backporting to its own header.
check-in: dc81f185 user: luismachuca tags: trunk
Changes

Changes to cxxomfort/cxxomfort/README.txt.

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
cxxcomfort Library for C++
--------------------------

C++ backports of nifty C++11 utilities (and more)
by Luis Machuca Bezzaza

Cxxomfort is a small, header-only library that backports features 
from more advanced Standards to previous ones, 
for example C++11 features are backported to C++03.
It was written to facilitate my working with the evolving C++ standard 
as I was getting back into the language. 
It is intended to reduce the amount and stress of code rewrite while at the 
same time assisting in backwards and forwards portability.

Documentation
-------------

Check the repository's web interface
http://ryan.gulix.cl/fossil.cgi/cxxomfort

It includes code samples and a listing of Nxxxx proposals or features 
of C++11 / C++1y that are added to this library.

Installation
------------

The overall installation procedure is as simple as this:

* clone repo






|
|
|
|
|
<
<




|


|
<







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
cxxcomfort Library for C++
--------------------------

C++ backports of nifty C++11 utilities (and more)
by Luis Machuca Bezzaza

Cxxomfort is a small, header-only library that backports features from more recent C++ Standards to previous ones, for example C++11 features are backported to C++03.

It was written to facilitate my working with the evolving C++ standard as I was getting back into the language, but it evolved to fulfill a more general purpose. 

It is intended to reduce the amount and stress of code rewrite while at the same time assisting in backwards and forwards portability of code.



Documentation
-------------

Check the repository's web interface - 
http://ryan.gulix.cl/fossil.cgi/cxxomfort

It includes code samples and a listing of Nxxxx proposals or features of C++11, C++14, C++1y that are added to this library.


Installation
------------

The overall installation procedure is as simple as this:

* clone repo

Changes to cxxomfort/cxxomfort/algorithm.hpp.

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
...
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
template<class It, class Pred>
It find_if_not(It ini, It fin, Pred f) {
    for (; ini != fin; ++ini) {
        if (!f(*ini)) {
            return ini;
        }
    }
    return fin;
}

//! Fills the sequence <var>[ini,fin)</var> with an incrementing sequence starting from @p i0 .
template <typename FwIt, typename T>
FwIt iota (FwIt ini, FwIt fin, T i0) {
    for(; ini!=fin; ++ini, ++i0) {*ini= i0; }
    return ini;
................................................................................
 * @}
 */

} //~namespace algorithm
} //~namespace cxxomfort




// These are in their own files
//#include "impl/03-minmax.hpp"
// included in c++11 onwards
#include "impl/11-is_xxx_of.hpp"
#include "impl/11-permutations.hpp"
// c++14 onwards
#include "impl/14-algorithm-equal.hpp"
// pending: #include "impl/modifying.hpp"
// c++17 onwards(?)
#include "impl/17-clamp.hpp"






#if (CXXOMFORT_CXX_STD < 2011) && (CXXO_COMPILER_SUPPORT_std_cxx11_algorithms == 0)
    #if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1)
    #pragma message CXXO_NOTICE("enabled C++11 <algorithm> support.")
    #endif

namespace std {

    //! using copy_if and others when in C++03.
    using ::cxxomfort::algorithm::copy_if;
    using ::cxxomfort::algorithm::copy_n;
    using ::cxxomfort::algorithm::partition_copy;







|







 







>
>











>
>
>



<
<
<







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
...
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
template<class It, class Pred>
It find_if_not(It ini, It fin, Pred f) {
    for (; ini != fin; ++ini) {
        if (!f(*ini)) {
            return ini;
        }
    }
    return fin; // < all the elements fulfill f
}

//! Fills the sequence <var>[ini,fin)</var> with an incrementing sequence starting from @p i0 .
template <typename FwIt, typename T>
FwIt iota (FwIt ini, FwIt fin, T i0) {
    for(; ini!=fin; ++ini, ++i0) {*ini= i0; }
    return ini;
................................................................................
 * @}
 */

} //~namespace algorithm
} //~namespace cxxomfort


#define CXXOMFORT_IMPLEMENTS_n1990 CXXO_BACKPORT()

// These are in their own files
//#include "impl/03-minmax.hpp"
// included in c++11 onwards
#include "impl/11-is_xxx_of.hpp"
#include "impl/11-permutations.hpp"
// c++14 onwards
#include "impl/14-algorithm-equal.hpp"
// pending: #include "impl/modifying.hpp"
// c++17 onwards(?)
#include "impl/17-clamp.hpp"

#if (defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1))
#pragma message CXXO_NOTICE("enabled <algorithm> support.")
#endif


#if (CXXOMFORT_CXX_STD < 2011) && (CXXO_COMPILER_SUPPORT_std_cxx11_algorithms == 0)




namespace std {

    //! using copy_if and others when in C++03.
    using ::cxxomfort::algorithm::copy_if;
    using ::cxxomfort::algorithm::copy_n;
    using ::cxxomfort::algorithm::partition_copy;

Changes to cxxomfort/cxxomfort/base/cstdint.hpp.

1
2
3
4
5
6
7
8
9
..
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
..
63
64
65
66
67
68
69
70
71
72
#ifndef CXXOMFORT_CSTDINT_HPP
#define CXXOMFORT_CSTDINT_HPP
/*
 * This header file redirects to the header providing
 * the standard integer types; in C++11 this is
 * <cstdint>, whereas in C++03 this is <stdint.h>
 */
#include "../config.hpp"
#define __STDC_LIMIT_MACROS
................................................................................
    #if defined(CXXOMFORT_NOTICES)  && (CXXOMFORT_NOTICES > 1)
        #pragma message CXXO_NOTICE("Including <cstdint> in C++11 mode")
    #endif
    #include <cstdint>
    #define CXXOMFORT_USING_NATIVE_stdint
#else
    #if 0
    // GCC and clang have a <stdlib.h>
        #error ("Unreachable.");
    #elif (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_CLANG)

        #if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1)
        #pragma message CXXO_NOTICE("cstdint forwarded to tr1/ <cstdint> [clang]")
        #endif
        #define __STDC_LIMIT_MACROS
        #include <tr1/cstdint>
        #define CXXOMFORT_USING_NATIVE_stdint

................................................................................
    #endif
    //#define __STDC_LIMIT_MACROS
    #include "../impl/pstdint.h"
    #define CXXOMFORT_USING_PSTDINT_stdint
#endif // using pstdint

#include <climits>

#endif // header

|
|







 







<


>







 







<


1
2
3
4
5
6
7
8
9
..
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
..
63
64
65
66
67
68
69

70
71
#ifndef CXXOMFORT_BASE_CSTDINT_HPP
#define CXXOMFORT_BASE_CSTDINT_HPP
/*
 * This header file redirects to the header providing
 * the standard integer types; in C++11 this is
 * <cstdint>, whereas in C++03 this is <stdint.h>
 */
#include "../config.hpp"
#define __STDC_LIMIT_MACROS
................................................................................
    #if defined(CXXOMFORT_NOTICES)  && (CXXOMFORT_NOTICES > 1)
        #pragma message CXXO_NOTICE("Including <cstdint> in C++11 mode")
    #endif
    #include <cstdint>
    #define CXXOMFORT_USING_NATIVE_stdint
#else
    #if 0

        #error ("Unreachable.");
    #elif (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_CLANG)
    // GCC and clang have a <stdlib.h>
        #if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1)
        #pragma message CXXO_NOTICE("cstdint forwarded to tr1/ <cstdint> [clang]")
        #endif
        #define __STDC_LIMIT_MACROS
        #include <tr1/cstdint>
        #define CXXOMFORT_USING_NATIVE_stdint

................................................................................
    #endif
    //#define __STDC_LIMIT_MACROS
    #include "../impl/pstdint.h"
    #define CXXOMFORT_USING_PSTDINT_stdint
#endif // using pstdint

#include <climits>

#endif // header

Changes to cxxomfort/cxxomfort/base/explicit_cast.hpp.

9
10
11
12
13
14
15


16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * * @c explicit_cast (as a synonym in C++11)
 * * @c CXXO_EXPLICIT_OPERATOR
 * 
 */

#include "../config.hpp"
#include "../base/move.hpp"



namespace cxxomfort {
namespace detail_explicit_cast {

#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_explicit_operator==0)
#if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 2)
    #pragma message CXXO_NOTICE("enabled explicit conversion operator emulation")
#endif

//! @ingroup base-features
template <typename T>
struct explicit_cast {
    T value;
    explicit_cast (T const& t) CXXO_NOEXCEPT : value(t) {}







>
>






|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 * * @c explicit_cast (as a synonym in C++11)
 * * @c CXXO_EXPLICIT_OPERATOR
 * 
 */

#include "../config.hpp"
#include "../base/move.hpp"
#define CXXOMFORT_IMPLEMENTS_n2333 CXXO_EMULATION()
#define CXXOMFORT_IMPLEMENTS_n2437 CXXO_EMULATION()

namespace cxxomfort {
namespace detail_explicit_cast {

#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_explicit_operator==0)
#if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 2)
    #pragma message CXXO_NOTICE("enabled 'explicit operator' emulation")
#endif

//! @ingroup base-features
template <typename T>
struct explicit_cast {
    T value;
    explicit_cast (T const& t) CXXO_NOEXCEPT : value(t) {}

Changes to cxxomfort/cxxomfort/base/iterator.hpp.

315
316
317
318
319
320
321



322
323

324
325
326
327
328
329
330
331
332
#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_std_iterator_helpers == 0)
    using ::cxxomfort::iterator::begin;
    using ::cxxomfort::iterator::end;
    using ::cxxomfort::iterator::cbegin;
    using ::cxxomfort::iterator::cend;
    using ::cxxomfort::iterator::rbegin;
    using ::cxxomfort::iterator::rend;



    using ::cxxomfort::iterator::next;
    using ::cxxomfort::iterator::prev;


#else
	using ::cxxomfort::iterator::cbegin;
	using ::cxxomfort::iterator::cend;
#endif
    //using ::cxxomfort::size; // not enabled yet
}

#endif







>
>
>


>









315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_std_iterator_helpers == 0)
    using ::cxxomfort::iterator::begin;
    using ::cxxomfort::iterator::end;
    using ::cxxomfort::iterator::cbegin;
    using ::cxxomfort::iterator::cend;
    using ::cxxomfort::iterator::rbegin;
    using ::cxxomfort::iterator::rend;
// GCC 4.4 already has next, prev in c++0x mode
    #if (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_GCC && CXXOMFORT_CXX_EMULATION == 2011)
    #else
    using ::cxxomfort::iterator::next;
    using ::cxxomfort::iterator::prev;
    #endif

#else
	using ::cxxomfort::iterator::cbegin;
	using ::cxxomfort::iterator::cend;
#endif
    //using ::cxxomfort::size; // not enabled yet
}

#endif

Changes to cxxomfort/cxxomfort/base/move.hpp.

2
3
4
5
6
7
8

9
10
11
12
13
14
15
..
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
#define CXXOMFORT_UTIL_MOVE_HPP

/**
 * @file cxxomfort/base/move.hpp
 * @brief Implements movable objects functionality in C++03 .
 *
 */


/*
 * Usage example
 *
template <class Resource> class holds_resource {
    private:
    CXXO_COPYABLE_MOVABLE(holds_resource);
................................................................................
      }
      return *this;
    }
};
*/

#include <cxxomfort/config.hpp> // c++11



#if ((CXXOMFORT_CXX_STD < 2011) && (CXXO_COMPILER_SUPPORT_rvref==0))
    #define CXXOMFORT_USING_MOVE_EMULATION 1
#endif






#if !defined (CXXOMFORT_USING_MOVE_EMULATION)
    #include "move-11.hpp"
    // end c++11
#else
    #if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1)
    #pragma message CXXO_NOTICE("enabled movable object emulation.")
    #endif
    #include "move-03.hpp"
// end c++11 / c++03
#endif

namespace cxxomfort {

/**







>







 







>
>




>
>
>
>






<
<
<







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
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
#define CXXOMFORT_UTIL_MOVE_HPP

/**
 * @file cxxomfort/base/move.hpp
 * @brief Implements movable objects functionality in C++03 .
 *
 */


/*
 * Usage example
 *
template <class Resource> class holds_resource {
    private:
    CXXO_COPYABLE_MOVABLE(holds_resource);
................................................................................
      }
      return *this;
    }
};
*/

#include <cxxomfort/config.hpp> // c++11
#define CXXOMFORT_IMPLEMENTS_n2118 CXXO_EMULATION()


#if ((CXXOMFORT_CXX_STD < 2011) && (CXXO_COMPILER_SUPPORT_rvref==0))
    #define CXXOMFORT_USING_MOVE_EMULATION 1
#endif

#if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 2)
#pragma message CXXO_NOTICE("enabled rvref and movable object emulation.")
#endif


#if !defined (CXXOMFORT_USING_MOVE_EMULATION)
    #include "move-11.hpp"
    // end c++11
#else



    #include "move-03.hpp"
// end c++11 / c++03
#endif

namespace cxxomfort {

/**

Changes to cxxomfort/cxxomfort/base/nullptr.hpp.

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
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces defined in this file:
 * 
 * * nullptr_t (also in namespace std)
 * * nullptr (also in namespace std)
 */

#include "../config.hpp"





#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_nullptr==0)
    #define CXXOMFORT_USING_nullptr
#endif


#if defined (CXXOMFORT_USING_nullptr)
    #if defined (CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 2)
    #pragma message CXXO_NOTICE("enabled nullptr support.")
    #endif


/*
 * This is marked as a system header mostly because of 
 * bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48914
 * where it is not possible to omit "nullptr is reserved" warnings.







<

>
>
>
>








|







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
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces defined in this file:
 * 
 * * nullptr_t (also in namespace std)
 * * nullptr (also in namespace std)
 */

#include "../config.hpp"
#define CXXOMFORT_IMPLEMENTS_n1601 CXXO_BACKPORT()
#define CXXOMFORT_IMPLEMENTS_n2214 CXXO_BACKPORT()



#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_nullptr==0)
    #define CXXOMFORT_USING_nullptr
#endif


#if defined (CXXOMFORT_USING_nullptr)
    #if defined (CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 2)
    #pragma message CXXO_NOTICE("enabled 'nullptr' backport.")
    #endif


/*
 * This is marked as a system header mostly because of 
 * bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48914
 * where it is not possible to omit "nullptr is reserved" warnings.

Changes to cxxomfort/cxxomfort/base/static_assert.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
#ifndef CXXOMFORT_SASSERT_HPP
#define CXXOMFORT_SASSERT_HPP
/**
 * @file static_assert.hpp
 * @brief Implements @c static_assert as a comfort utility for C++03.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 * @license MIT License (see LICENSE.txt)
 *
 * Interfaces defined in this file:
 * 
 * * @c static_assert
 */

#include "../config.hpp"




#define CXXOMFORT_JOIN(a,b) a##b
#define CXXOMFORT_JOINX(a,b) CXXOMFORT_JOIN(a,b)

#if (CXXOMFORT_CXX_STD < 2011)
#if (CXXO_COMPILER_SUPPORT_static_assert == 0) // static_assert is not supported
    #define CXXOMFORT_USING_static_assert
#endif
#endif

// implementation

#if defined(CXXOMFORT_USING_static_assert)
    #if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 2)
    #pragma message CXXO_NOTICE("enabled static_assert support.")
    #endif

/*
 * This is marked as a system header 
 * as it uses the name of a C++11 reserved word as an identifier.
 */
#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC \




|









>
>
>
>













|







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
#ifndef CXXOMFORT_SASSERT_HPP
#define CXXOMFORT_SASSERT_HPP
/**
 * @file static_assert.hpp
 * @brief Implements @c static_assert (n1720) as a comfort utility for C++03.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 * @license MIT License (see LICENSE.txt)
 *
 * Interfaces defined in this file:
 * 
 * * @c static_assert
 */

#include "../config.hpp"
#define CXXOMFORT_IMPLEMENTS_n1604 CXXO_EMULATION()
#define CXXOMFORT_IMPLEMENTS_n1720 CXXO_EMULATION()


#define CXXOMFORT_JOIN(a,b) a##b
#define CXXOMFORT_JOINX(a,b) CXXOMFORT_JOIN(a,b)

#if (CXXOMFORT_CXX_STD < 2011)
#if (CXXO_COMPILER_SUPPORT_static_assert == 0) // static_assert is not supported
    #define CXXOMFORT_USING_static_assert
#endif
#endif

// implementation

#if defined(CXXOMFORT_USING_static_assert)
    #if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 2)
    #pragma message CXXO_NOTICE("enabled 'static_assert' emulation.")
    #endif

/*
 * This is marked as a system header 
 * as it uses the name of a C++11 reserved word as an identifier.
 */
#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC \

Changes to cxxomfort/cxxomfort/config.hpp.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
..
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
...
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
...
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
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382
383












384
385
386
387
388
//! Library version and release date as YYYYMM
#define CXXOMFORT_DATE 201707
//! Defines the library version (WARNING: to be deprecated)
#define CXXOMFORT_VERSION 52

#define CXXO_STRINGIZE_IMPL(x) #x
#define CXXO_STRINGIZE(x) CXXO_STRINGIZE_IMPL(x)


//
// Standard Mode
//

//! Year of the standard in use (the year part in @c __cplusplus ).
#define CXXOMFORT_CXX_STD (__cplusplus/100)
................................................................................
//

#define CXXO_VALUE_COMPILER_GCC 101
#define CXXO_VALUE_COMPILER_DIGITALMARS 102
#define CXXO_VALUE_COMPILER_MSC 103
#define CXXO_VALUE_COMPILER_CLANG 104


//------------------------------------------------
/*
 * List of C++ features for documentation
 * 
 * N1720 - static_assert
 * N1811 - long long
 * N1984, N2546 - new 'auto' semantics
 * N2118 - rvalue references
 * N2341 - alignment (alignof, alignas, aligned_storage, aligned_union)
 * N2346 - defaulted and deleted members
 * N2347 - scoped enums
 * N2431 - null pointer constant
 * N2437 - explicit conversion operators
 * N2439 - rvalue references for *this
 * N2657 - local types as template arguments
 * N2765 - user-defined literals
 * N2930 - range-based for loop
 * 
 */

//
// Set different flags according to the features 
// supported by the compiler
//










//! If compiler provides support for alignment tools (@c alignas , etc).
#define CXXO_COMPILER_SUPPORT_alignment_tools 0
//! If compiler provides support for @c alignof(T) .
#define CXXO_COMPILER_SUPPORT_alignof 0
//! If compiler provides support for <code>[[__attribute__]]</code>.
#define CXXO_COMPILER_SUPPORT_attribute 0
//! If compiler supports new (type-deduction) semantics for @c auto .
#define CXXO_COMPILER_SUPPORT_auto 0
//! If compiler provides support for @c constexpr .
#define CXXO_COMPILER_SUPPORT_constexpr 0
//! If compiler provides support for C++14's relaxed form of @c constexpr .
#define CXXO_COMPILER_SUPPORT_constexpr_relaxed 0
//! If compiler supports @c decltype(expr) .
#define CXXO_COMPILER_SUPPORT_decltype 0
//! If compiler provides support for <code>=default</code>-ed and <code>=delete</code>-d members.
#define CXXO_COMPILER_SUPPORT_default_delete 0
//! If compiler provides support for scoped enumerations ie.: <code>enum class...</code>.
#define CXXO_COMPILER_SUPPORT_enum_class 0
//! If compiler provides support for <code>explicit operator ...</code> casts.
#define CXXO_COMPILER_SUPPORT_explicit_operator 0
//! If compiler provides support for range-for.
#define CXXO_COMPILER_SUPPORT_foreach 0
//! If compiler provides support for @c std::initializer_list .
#define CXXO_COMPILER_SUPPORT_initializer_list 0
//! If compiler provides support for local and unnamed types as template arguments.
#define CXXO_COMPILER_SUPPORT_local_types 0
//! If compiler provides support for @c noexcept *AND* is_noexcept-traits.
#define CXXO_COMPILER_SUPPORT_noexcept 0
//! If compiler provides support for @c nullptr  and @c std::nullptr_t .
#define CXXO_COMPILER_SUPPORT_nullptr 0
//! If compiler provides support for @c T&& .
#define CXXO_COMPILER_SUPPORT_rvref 0
//! If compiler provides support for @c static_assert .
#define CXXO_COMPILER_SUPPORT_static_assert 0
//! If compiler provides support for the new C++11 std algorithms.
#define CXXO_COMPILER_SUPPORT_std_cxx11_algorithms 0
//! If compiler provides support for the new C++11 helpers std::begin, std::end.
#define CXXO_COMPILER_SUPPORT_std_iterator_helpers 0
//! If compiler provides support for std::next, std::prev.
#define CXXO_COMPILER_SUPPORT_std_iterator_helpers_next_prev 0
//! If compiler provides support for the new C++11 helpers std::enable_if, std::conditional.
................................................................................
#define CXXO_COMPILER_SUPPORT_std_metaprogramming_helpers 0
//! If compiler provides support for the <code>std::is_[trivially|nothrow]_...</code> traits.
#define CXXO_COMPILER_SUPPORT_std_is_trivially 0
//! If compiler provides support for C++11's 'common_type'.
#define CXXO_COMPILER_SUPPORT_std_cxx11_common_type 0
//! If compiler provides support for the "is_constructible", "is_assignable", and similar traits.
#define CXXO_COMPILER_SUPPORT_std_cxx11_constructible_traits 0
//! If compiler includes tr1/random header in c++03 mode
#define CXXO_COMPILER_SUPPORT_tr1_random 0
//! If compiler includes tr1/type_traits header in c++03 mode
#define CXXO_COMPILER_SUPPORT_tr1_type_traits 0
//! If compiler provides support for @c __typeof__ in C++03.
#define CXXO_COMPILER_SUPPORT_typeof 0
//! If compiler provides support for @c unique_ptr<T> .
#define CXXO_COMPILER_SUPPORT_unique_ptr 0
//! If compiler provides support for variadic templates.
#define CXXO_COMPILER_SUPPORT_variadic 0





//! If compiler provides support for variadic macros (<code>__VA_ARG__</code>).
#define CXXO_COMPILER_SUPPORT_va_args 0



//------------------------------------------------

// Detect CXX_STD and operation mode (initial)


#if (__cplusplus >= 201103L && __cplusplus < 201402L)
    #undef  CXXOMFORT_CXX_STD
    #define CXXOMFORT_CXX_STD 2011
#elif (__cplusplus >= 201402L)
    #undef  CXXOMFORT_CXX_STD
    #define CXXOMFORT_CXX_STD 2014
#endif


/*
 * Detect compilers and apply specific configurations.
 */
#if 0
#elif defined(__clang__)
    #include "./config/clang.hpp"
................................................................................
    #define CXXOMFORT_COMPILER_VERSION 0
    #define CXXO_NOTICE(msg) _Pragma(message ("WARNING - " msg))
    #if defined(CXXOMFORT_NOTICES)
        #pragma message CXXO_WARNING("Found an undetermined compiler.")
    #endif
#endif





/*
 * Set up for c++14
 */
#if (defined(CXXOMFORT_NOTICES))
    #if (CXXOMFORT_CXX_STD == 2014)
        #pragma message CXXO_NOTICE("detected C++14 or above mode")
    #elif (CXXOMFORT_CXX_STD == 2011)
        #pragma message CXXO_NOTICE("detected C++11 mode")
    #elif (CXXOMFORT_CXX_STD > 1 && CXXOMFORT_CXX_STD < 2011)
        #pragma message CXXO_NOTICE("detected C++03 or basic mode")
    #endif

    #if (CXXOMFORT_CXX_EMULATION == 2011) 
        #pragma message CXXO_NOTICE("running in emulation / c++0x mode")
    #elif (CXXOMFORT_CXX_EMULATION == 2014)
        #pragma message CXXO_NOTICE("running in emulation / c++1y mode")
    #endif



#endif

//
// Macros that conditionally generate code for C++11, C++14

#if (CXXOMFORT_CXX_STD < 2011)
................................................................................
// Evaluates to noexcept where noexcept is supported
#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_noexcept == 0)
#define CXXO_NOEXCEPT
#else
#define CXXO_NOEXCEPT noexcept
#endif



















//
// ---------------------------------------------------------
//

/*
 * Set up the minimal configuration.
 * This loads three headers whose features are used all across this library.
 */
#include CXXO_INCLUDE_SYS(cstddef) // namespace std, etc
#include CXXO_INCLUDE_SYS(cstdlib) // basic system
#include CXXO_INCLUDE_SYS(iterator) // basics for iterator








/*
 * Utility macro to declare variadic (pseudovariadic in C++03) template members
 */
#include "impl/pseudovariadic.hpp"
 

................................................................................
//
namespace cxxomfort {
//! Information about the library support
const struct info { 
    enum {
    //! library version
    version = CXXOMFORT_VERSION , 
    date = CXXOMFORT_DATE ,
    //! compiler identification code
    compilerid = CXXOMFORT_COMPILER_ID ,
    //! compiler version code (usually <code>100*major+minor</code>)
    compilerversion = CXXOMFORT_COMPILER_VERSION ,
    //! value of the standard
    cxx_std = CXXOMFORT_CXX_STD ,
    //! level of support of C++11 features in C++11 emulation / c++0x mode
    cxx_emulation = CXXOMFORT_CXX_EMULATION 

    };
    
    /* struct */ 
} $ = {};

template <typename SS> 
static void output_info (SS& os) {
    os<< "(cxxomfort:"<< $.version<< ' '<< $.date<< " c"<< $.compilerid<< "."<< $.compilerversion
      << " std"<< $.cxx_std<< " emu"<< $.cxx_emulation<< " )";
    //return os;
}













// ~::cxxomfort
}

#endif







>







 







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




>
>
>
>
>
>
>
>
>






|

|

|
<
<

|

|

|

|

|

|

|

|

|

|

|







 







<
<
<
<
|
|



|
>
>
>
>
>
|
|







>







>







 







>
>
>
>

|

|









|

|

>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












>
>
>
>
>
>







 







|







|
>







|
|


>
>
>
>
>
>
>
>
>
>
>
>





12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
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
...
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
...
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
...
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
//! Library version and release date as YYYYMM
#define CXXOMFORT_DATE 201707
//! Defines the library version (WARNING: to be deprecated)
#define CXXOMFORT_VERSION 52

#define CXXO_STRINGIZE_IMPL(x) #x
#define CXXO_STRINGIZE(x) CXXO_STRINGIZE_IMPL(x)
#define CXXO_JOIN(x,y) x##y

//
// Standard Mode
//

//! Year of the standard in use (the year part in @c __cplusplus ).
#define CXXOMFORT_CXX_STD (__cplusplus/100)
................................................................................
//

#define CXXO_VALUE_COMPILER_GCC 101
#define CXXO_VALUE_COMPILER_DIGITALMARS 102
#define CXXO_VALUE_COMPILER_MSC 103
#define CXXO_VALUE_COMPILER_CLANG 104






















//
// Set different flags according to the features 
// supported by the compiler
//

//! If compiler includes tr1/random header in c++03 mode
#define CXXO_COMPILER_SUPPORT_tr1_random 0
//! If compiler includes tr1/type_traits header in c++03 mode
#define CXXO_COMPILER_SUPPORT_tr1_type_traits 0
//! If compiler provides support for @c __typeof__ in C++03.
#define CXXO_COMPILER_SUPPORT_typeof 0
//! If compiler provides support for variadic macros (<code>__VA_ARG__</code>).
#define CXXO_COMPILER_SUPPORT_va_args 0

//! If compiler provides support for alignment tools (@c alignas , etc).
#define CXXO_COMPILER_SUPPORT_alignment_tools 0
//! If compiler provides support for @c alignof(T) .
#define CXXO_COMPILER_SUPPORT_alignof 0
//! If compiler provides support for <code>[[__attribute__]]</code>.
#define CXXO_COMPILER_SUPPORT_attribute (CXXOMFORT_CXX_STD >= 2011)
//! If compiler supports new (type-deduction) semantics for @c auto .
#define CXXO_COMPILER_SUPPORT_auto (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for @c constexpr .
#define CXXO_COMPILER_SUPPORT_constexpr (CXXOMFORT_CXX_STD>=2011)


//! If compiler supports @c decltype(expr) .
#define CXXO_COMPILER_SUPPORT_decltype (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for <code>=default</code>-ed and <code>=delete</code>-d members.
#define CXXO_COMPILER_SUPPORT_default_delete (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for scoped enumerations ie.: <code>enum class...</code>.
#define CXXO_COMPILER_SUPPORT_enum_class (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for <code>explicit operator ...</code> casts.
#define CXXO_COMPILER_SUPPORT_explicit_operator (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for range-for.
#define CXXO_COMPILER_SUPPORT_foreach (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for @c std::initializer_list .
#define CXXO_COMPILER_SUPPORT_initializer_list (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for local and unnamed types as template arguments.
#define CXXO_COMPILER_SUPPORT_local_types (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for @c noexcept *AND* is_noexcept-traits.
#define CXXO_COMPILER_SUPPORT_noexcept (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for @c nullptr  and @c std::nullptr_t .
#define CXXO_COMPILER_SUPPORT_nullptr (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for @c T&& .
#define CXXO_COMPILER_SUPPORT_rvref (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for @c static_assert .
#define CXXO_COMPILER_SUPPORT_static_assert (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for the new C++11 std algorithms.
#define CXXO_COMPILER_SUPPORT_std_cxx11_algorithms 0
//! If compiler provides support for the new C++11 helpers std::begin, std::end.
#define CXXO_COMPILER_SUPPORT_std_iterator_helpers 0
//! If compiler provides support for std::next, std::prev.
#define CXXO_COMPILER_SUPPORT_std_iterator_helpers_next_prev 0
//! If compiler provides support for the new C++11 helpers std::enable_if, std::conditional.
................................................................................
#define CXXO_COMPILER_SUPPORT_std_metaprogramming_helpers 0
//! If compiler provides support for the <code>std::is_[trivially|nothrow]_...</code> traits.
#define CXXO_COMPILER_SUPPORT_std_is_trivially 0
//! If compiler provides support for C++11's 'common_type'.
#define CXXO_COMPILER_SUPPORT_std_cxx11_common_type 0
//! If compiler provides support for the "is_constructible", "is_assignable", and similar traits.
#define CXXO_COMPILER_SUPPORT_std_cxx11_constructible_traits 0




//! If compiler provides support for trailing return types.
#define CXXO_COMPILER_SUPPORT_trailing_returns (CXXOMFORT_CXX_STD>=2011)
//! If compiler provides support for @c unique_ptr<T> .
#define CXXO_COMPILER_SUPPORT_unique_ptr 0
//! If compiler provides support for variadic templates.
#define CXXO_COMPILER_SUPPORT_variadic (CXXOMFORT_CXX_STD>=2011)

//! If compiler provides support for C++14's relaxed form of @c constexpr .
#define CXXO_COMPILER_SUPPORT_constexpr_relaxed (CXXOMFORT_CXX_STD>=2014)
//! If compiler supports <functional> 's transparent functors.
#define CXXO_COMPILER_SUPPORT_functional_transparent (CXXOMFORT_CXX_STD >= 2014)
//! If compiler provides support for "integer_sequence".
#define CXXO_COMPILER_SUPPORT_integer_sequence (CXXOMFORT_CXX_STD >= 2014)



//------------------------------------------------

// Detect CXX_STD and operation mode (initial)

/*
#if (__cplusplus >= 201103L && __cplusplus < 201402L)
    #undef  CXXOMFORT_CXX_STD
    #define CXXOMFORT_CXX_STD 2011
#elif (__cplusplus >= 201402L)
    #undef  CXXOMFORT_CXX_STD
    #define CXXOMFORT_CXX_STD 2014
#endif
*/

/*
 * Detect compilers and apply specific configurations.
 */
#if 0
#elif defined(__clang__)
    #include "./config/clang.hpp"
................................................................................
    #define CXXOMFORT_COMPILER_VERSION 0
    #define CXXO_NOTICE(msg) _Pragma(message ("WARNING - " msg))
    #if defined(CXXOMFORT_NOTICES)
        #pragma message CXXO_WARNING("Found an undetermined compiler.")
    #endif
#endif

#if (defined(CXXOMFORT_NOTICES))
    #pragma message CXXO_NOTICE("compiler found : " CXXO_STRINGIZE(CXXOMFORT_COMPILER_ID) "." CXXO_STRINGIZE(CXXOMFORT_COMPILER_VERSION)  )
    #pragma message CXXO_NOTICE("library mode   : ver=" CXXO_STRINGIZE(CXXOMFORT_DATE) " std=" CXXO_STRINGIZE(CXXOMFORT_CXX_STD) ",emu=" CXXO_STRINGIZE(CXXOMFORT_CXX_EMULATION) )

/*
 * Set up more friendly messages
 */
    #if (CXXOMFORT_NOTICES > 1)
    #if (CXXOMFORT_CXX_STD == 2014)
        #pragma message CXXO_NOTICE("detected C++14 or above mode")
    #elif (CXXOMFORT_CXX_STD == 2011)
        #pragma message CXXO_NOTICE("detected C++11 mode")
    #elif (CXXOMFORT_CXX_STD > 1 && CXXOMFORT_CXX_STD < 2011)
        #pragma message CXXO_NOTICE("detected C++03 or basic mode")
    #endif

    #if (CXXOMFORT_CXX_EMULATION == 2011) 
        #pragma message CXXO_NOTICE("running in emulation / c++0x mode (c++11)")
    #elif (CXXOMFORT_CXX_EMULATION == 2014)
        #pragma message CXXO_NOTICE("running in emulation / c++1y mode (c++14)")
    #endif
    
    #endif // friendly notices

#endif

//
// Macros that conditionally generate code for C++11, C++14

#if (CXXOMFORT_CXX_STD < 2011)
................................................................................
// Evaluates to noexcept where noexcept is supported
#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_noexcept == 0)
#define CXXO_NOEXCEPT
#else
#define CXXO_NOEXCEPT noexcept
#endif

//
// CXXO_NOEXCEPTNOTHROW
// Evaluates to noexcept where noexcept is supported, and to throw() in C++03
#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_noexcept == 0)
#define CXXO_NOEXCEPTNOTHROW throw() 
#else
#define CXXO_NOEXCEPTNOTHROW noexcept
#endif

//
// CXXO_NOEXCEPT_COND(...)
// Evaluates to the noexcept of the condition in C++11 onwards, and to nothing in C++03
#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_noexcept == 0)
#define CXXO_NOEXCEPT_COND(...)
#else
#define CXXO_NOEXCEPT_COND(...) noexcept(...)
#endif

//
// ---------------------------------------------------------
//

/*
 * Set up the minimal configuration.
 * This loads three headers whose features are used all across this library.
 */
#include CXXO_INCLUDE_SYS(cstddef) // namespace std, etc
#include CXXO_INCLUDE_SYS(cstdlib) // basic system
#include CXXO_INCLUDE_SYS(iterator) // basics for iterator

#include "config/_has.hpp"
#define _CXXOMFORT_IMPLEMENTS(nn) (( CXXO_JOIN(CXXOMFORT_IMPLEMENTS_n,nn) > 0))
#define CXXOMFORT_IMPLEMENTS(nn) _CXXOMFORT_IMPLEMENTS(nn)

// this command in a shell reveals all nxxxx proposals implemented by this library:
// find -type f -iname '*.hpp' | xargs egrep -o "CXXOMFORT_IMPLEMENTS_n([0-9]+)\b"

/*
 * Utility macro to declare variadic (pseudovariadic in C++03) template members
 */
#include "impl/pseudovariadic.hpp"
 

................................................................................
//
namespace cxxomfort {
//! Information about the library support
const struct info { 
    enum {
    //! library version
    version = CXXOMFORT_VERSION , 
    date = CXXOMFORT_DATE, 
    //! compiler identification code
    compilerid = CXXOMFORT_COMPILER_ID ,
    //! compiler version code (usually <code>100*major+minor</code>)
    compilerversion = CXXOMFORT_COMPILER_VERSION ,
    //! value of the standard
    cxx_std = CXXOMFORT_CXX_STD ,
    //! level of support of C++11 features in C++11 emulation / c++0x mode
    cxx_emulation = CXXOMFORT_CXX_EMULATION , 
    cplusplus = __cplusplus
    };
    
    /* struct */ 
} $ = {};

template <typename SS> 
static void output_info (SS& os) {
    os<< "(cxxomfort="<< $.version<< " date="<< $.date<< " compilerid="<< $.compilerid<< " compilerversion="<< $.compilerversion
      << " cplusplus="<< $.cplusplus<< " std="<< $.cxx_std<< " emulation="<< $.cxx_emulation<< " )";
    //return os;
}

#if 0 // uncomment only for diagnostics and wiki work
template <typename SS> 
static void output_info_row (SS& os) {
    using namespace std;
    os<< "    <code>"<< setw(3)<< setfill(' ')<< $.compilerid<< "</code>";
    os<< " <code>"<< setw(4)<< setfill('0')<< $.compilerversion<< setfill(' ')<< "</code>";
    os<< "  </td><td>  <code>"<< setw(4)<< $.cxx_std<< "</code>  </td><td>  <code>"<< setw(4)<< $.cxx_emulation<< "</code>  </td>"
    ;
    //return os;
}
#endif

// ~::cxxomfort
}

#endif

Added cxxomfort/cxxomfort/config/_has.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
#ifndef CXXOMFORT_CONFIG_C_HAS_HPP
#define CXXOMFORT_CONFIG_C_HAS_HPP

/*
 * Starting with cxxomfort 0.6, headers also provide a macro describing the 
 * support of feature they implement. 
 */

//! Value returned for feature macro when cxxomfort is redirecting the feature to the compiler's native implementation.
#define CXXO_REDIRECT_NATIVE() (9001u)
//! Value returned for feature macro when cxxomfort is implementing a backport.
#define CXXO_BACKPORT() (4001u)
//! Value returned for feature macro when cxxomfort provides an emulation.
#define CXXO_EMULATION() (5001u)
#define CXXO_LIBRARY() (1001u)

//------------------------------------------------
/*
 * List of C++ features for documentation
 * 
 * c++03:
 * c++11:
 * 
 * n1601, n2214, n2431 - null pointer constant
 * n1604, n1720 - static_assert
 * n1811 - long long
 * n1836 - built-in type traits
 * n1978, n2343 - decltype
 * n1984, N2546 - new 'auto' semantics
 * n1986 - delegating constructors
 * n1990 - minmax
 * n2070 - decay
 * n2118 - rvalue references, std::move
 * n2235 - constexpr (c++11)
 * n2240 - enable_if and conditional
 * n2243, n2930 - range-based for loop
 * n2249 - new character types
 * n2258 - template aliases ("using =")
 * n2333, n2437 - explicit conversion operators
 * n2341 - alignment (alignof, alignas, aligned_storage, aligned_union)
 * n2346 - defaulted and deleted members
 * n2347 - scoped enums
 * n2349 - new character types (char16, char32)
 * n2439 - rvalue references for *this
 * n2442 - raw string literals
 * n2540 - inheriting constructors
 * n2541 - trailing return type for functions (->)
 * n2555 - variadic templates
 * n2569 - any, all, none algorithms; lexicographical compare 3-way
 * n2657 - local types as template arguments
 * n2672 - initializer_list
 * n2761 - attributes
 * n2765 - user-defined literals
 * n2844 - rvalue references 2.0
 * n2947 - additional C++0x traits (is_trivially... and is_literal...)
 * 
 * c++14:
 * 
 * n3421 - functional's transparent operators
 * n3584, n3670 - get<>(std:tuple) by type
 * n3652 - relaxed constexpr (c++14)
 * n3656 - make_unique
 * n3638 - return type deduction for normal functions
 * n3654 - quoted
 * n3658 - integer_sequence
 * n3668 - exchange
 * n3671 - improved equal, mismatch
 * n3829 - apply (call a function with a tuple as pack of arguments)
 * 
 * c++17:
 * 
 * n3840, n4282
 * n3840, n4282 - observer_ptr, the world's dumbest smart pointer
 * n3928 - extended static_assert
 * n3911 - make_void, void_t
 * n4061 - gcd, lcm
 * n4076 - not_fn
 * n4380 - as_const
 * 
 * external proposals as of Aug 2017:
 * 
 * n1878, n3527 - optional<T>, nullable type wrapper
 * n2648 - dynarray<T>, ctor-sized vector (functionally later fixed_vector)
 * n3334 - array_ref<T>, range view over a contiguous sequence
 * n3350 - std::range (minimum proposal)
 * n3500 - new assert variants
 * n4017 - nonmember size (<iterator>)
 * n3928 - static_assert without message
 * 
 
 * 
 */



#endif

Changes to cxxomfort/cxxomfort/config/gcc.hpp.

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



        #define CXXO_COMPILER_SUPPORT_unique_ptr 1
        #undef  CXXO_COMPILER_SUPPORT_variadic
        #define CXXO_COMPILER_SUPPORT_variadic 1
    #else
    #endif
#endif

// ----

#if (CXXOMFORT_COMPILER_VERSION >= 407)
    #if defined(__GXX_EXPERIMENTAL_CXX0X__)
        #undef  CXXO_COMPILER_SUPPORT_constexpr
        #define CXXO_COMPILER_SUPPORT_constexpr 1
    #endif
#endif







#if (CXXOMFORT_COMPILER_VERSION >= 408)
    #if defined(__GXX_EXPERIMENTAL_CXX0X__)
    #undef  CXXO_COMPILER_SUPPORT_attribute
    #define CXXO_COMPILER_SUPPORT_attribute 1
    #undef  CXXO_COMPILER_SUPPORT_alignment_tools
    #define CXXO_COMPILER_SUPPORT_alignment_tools 1
    #undef  CXXO_COMPILER_SUPPORT_decltype
    #define CXXO_COMPILER_SUPPORT_decltype 1
    // 4.8 is considered to have full C++11 support for practical purposes
    // but it's untested so far
    #endif
#endif














#endif










<
<






>
>
>
>
>
>














>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
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
        #define CXXO_COMPILER_SUPPORT_unique_ptr 1
        #undef  CXXO_COMPILER_SUPPORT_variadic
        #define CXXO_COMPILER_SUPPORT_variadic 1
    #else
    #endif
#endif



#if (CXXOMFORT_COMPILER_VERSION >= 407)
    #if defined(__GXX_EXPERIMENTAL_CXX0X__)
        #undef  CXXO_COMPILER_SUPPORT_constexpr
        #define CXXO_COMPILER_SUPPORT_constexpr 1
    #endif
#endif

// GCC 4.8 onwards set up support for C++14 (--std=c++1y or --std=c++14)

#if (CXXOMFORT_CXX_STD == 2013)
    #define CXXOMFORT_CXX_EMULATION 2014
#endif

#if (CXXOMFORT_COMPILER_VERSION >= 408)
    #if defined(__GXX_EXPERIMENTAL_CXX0X__)
    #undef  CXXO_COMPILER_SUPPORT_attribute
    #define CXXO_COMPILER_SUPPORT_attribute 1
    #undef  CXXO_COMPILER_SUPPORT_alignment_tools
    #define CXXO_COMPILER_SUPPORT_alignment_tools 1
    #undef  CXXO_COMPILER_SUPPORT_decltype
    #define CXXO_COMPILER_SUPPORT_decltype 1
    // 4.8 is considered to have full C++11 support for practical purposes
    // but it's untested so far
    #endif
#endif

#if (CXXOMFORT_COMPILER_VERSION >= 409)
    #if defined(__GXX_EXPERIMENTAL_CXX0X__)
    #undef  CXXO_COMPILER_SUPPORT_attribute
    #define CXXO_COMPILER_SUPPORT_attribute 1
    #undef  CXXO_COMPILER_SUPPORT_alignment_tools
    #define CXXO_COMPILER_SUPPORT_alignment_tools 1
    #undef  CXXO_COMPILER_SUPPORT_decltype
    #define CXXO_COMPILER_SUPPORT_decltype 1
    // 4.8 is considered to have full C++11 support for practical purposes
    // but it's untested so far
    #else
    #undef CXXOMFORT_CXX_STD
    #define CXXOMFORT_CXX_STD 2003
    #endif
#endif

#endif

Changes to cxxomfort/cxxomfort/config/msc.hpp.

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
    #define CXXO_COMPILER_SUPPORT_std_cxx11_algorithms 1
    #undef  CXXO_COMPILER_SUPPORT_std_cxx11_constructible_traits
    #define CXXO_COMPILER_SUPPORT_std_cxx11_constructible_traits 1
    #undef  CXXO_COMPILER_SUPPORT_std_iterator_helpers
    #define CXXO_COMPILER_SUPPORT_std_iterator_helpers 1
    #undef  CXXO_COMPILER_SUPPORT_std_metaprogramming_helpers
    #define CXXO_COMPILER_SUPPORT_std_metaprogramming_helpers 1
    #undef  CXXO_COMPILER_SUPPORT_alignof
    #define CXXO_COMPILER_SUPPORT_alignof 1
    #undef  CXXO_COMPILER_SUPPORT_unique_ptr
    #define CXXO_COMPILER_SUPPORT_unique_ptr 1
    
#endif

// -- TODO -- get my claws on a MSVC 2012

// -- END Microsoft C++ Compiler --
#endif







|
|









70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
    #define CXXO_COMPILER_SUPPORT_std_cxx11_algorithms 1
    #undef  CXXO_COMPILER_SUPPORT_std_cxx11_constructible_traits
    #define CXXO_COMPILER_SUPPORT_std_cxx11_constructible_traits 1
    #undef  CXXO_COMPILER_SUPPORT_std_iterator_helpers
    #define CXXO_COMPILER_SUPPORT_std_iterator_helpers 1
    #undef  CXXO_COMPILER_SUPPORT_std_metaprogramming_helpers
    #define CXXO_COMPILER_SUPPORT_std_metaprogramming_helpers 1
//    #undef  CXXO_COMPILER_SUPPORT_alignof
//    #define CXXO_COMPILER_SUPPORT_alignof 1
    #undef  CXXO_COMPILER_SUPPORT_unique_ptr
    #define CXXO_COMPILER_SUPPORT_unique_ptr 1
    
#endif

// -- TODO -- get my claws on a MSVC 2012

// -- END Microsoft C++ Compiler --
#endif

Added cxxomfort/cxxomfort/cstd/experimental/memory.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
#ifndef CXXOMFORT_STD_EXPERIMENTAL_MEMORY
#define CXXOMFORT_STD_EXPERIMENTAL_MEMORY
#include "../../extras/observer_ptr.hpp"

namespace std {
namespace experimental {
    using namespace ::cxxomfort::extras::observer_ptr;
}
}

#endif

Changes to cxxomfort/cxxomfort/cstd/experimental/optional.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef CXXOMFORT_STD_OPTIONAL
#define CXXOMFORT_STD_OPTIONAL
/**
 * @file cstd/optional
 * @brief CSTD-style header for @c optional 
 */
#include "../../extras/optional.hpp"
#include "../../extras/optional-io.hpp"
#include "../../extras/optional-relational.hpp"

// add it to namespace std::experimental
namespace std {
namespace experimental {
    using namespace cxxomfort::extras::optional;
}
}

#endif
|
|

|


|
|
<









1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
#ifndef CXXOMFORT_STD_EXPERIMENTAL_MEMORY
#define CXXOMFORT_STD_EXPERIMENTAL_MEMORY
/**
 * @file cstd/experimental/memory
 * @brief CSTD-style header for @c optional 
 */
//#include "../../extras/memory.hpp"
#include "../../extras/optional.hpp"


// add it to namespace std::experimental
namespace std {
namespace experimental {
    using namespace cxxomfort::extras::optional;
}
}

#endif

Added cxxomfort/cxxomfort/cstdint.hpp.







































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef CXXOMFORT_CSTDINT_HPP
#define CXXOMFORT_CSTDINT_HPP
/**
 * @file cxxomfort/cstdint.hpp
 * @brief <cstdint> wrapper
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 *
 */

#include <cxxomfort/config.hpp>
#if (defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1))
#pragma message CXXO_NOTICE("enabled <cstdint> support.")
#endif
#include <cxxomfort/base/cstdint.hpp>
#include <cxxomfort/base.hpp>


#endif

Changes to cxxomfort/cxxomfort/cxxomfort.hpp.

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
#include "config.hpp"

//
// Main Features
//
// (pending minor reorganization as of v0.49)
#include "base.hpp"
#include "algorithms.hpp" // <algorithm> additions (copy_if, minmax, etc...)

#include "functional.hpp" // <functional> additions (transparent functors, etc)
#include "limits.hpp" // compile-time integral limits
#include "memory.hpp" // <memory> additions (pointer_traits, alignof, unique_ptr, etc...)
#include "util/type_traits.hpp" // basic type_traits
#include "impl/regex-esc.hpp" // CXXO_R for raw regex patterns
#include "utility.hpp" // declval, exchange, pair...
#include "string.hpp" // string function helpers (eg.: to_string)
#include "type_traits.hpp" // common_type, decay, is_literal, is_null_pointer, ...
#include "library.hpp" // cxxomfort library features
#include "sequences.hpp" // sequence helpers, seq_<T>()
#include "using.hpp"


/*
 * Features added to C++11
 * 
 * n1720 - static_assert
 * n1811 - long long
 * n1836 - built-in type traits
 * n1984 - auto (0.9)
 * n1986 - delegating constructors
 * n2118 - rvalue-refs, std::move (see also n2844)
 * n2235 - constexpr
 * n2341 - alignas, alignof
 * n2343 - decltype
 * n2346 - =default, =delete
 * n2347 - strongly typed enums
 * n2249 - new character types
 * n2431 - nullptr
 * n2437 - explicit operator
 * n2442 - raw string literals
 * n2540 - inheriting constructors
 * n2541 - ->return type for functions
 * n2546 - auto (1.0)
 * n2555 - variadic templates 1.0
 * n2672 - initializer_list
 * n2657 - local types as arguments for templates
 * n2761 - Attributes
 * n2844 - rvalue-refs 2.0
 * n2930 - range for loop
 * 
 * Features added to C++14:
 * 
 * n3421 - transparent functional operators using void
 * n3584 - tuple get<type>
 * n3656 - make_unique
 * n3668 - exchange
 * n3829 - call a function with an unpacked tuple as arguments
 * 
 */
 
/* 
 * Proposals implemented in cxxomfort as of January 2015:
 * 
 * n1878 - optional<T>
 * n2648 - dynarray<T>
 * n3334 - array_ref<T>
 * n3350 - std::range (TBA)
 * n3824 - make_array (for c++11)
 * n4017 - nonmember size(...)
 * n4155 - nonmember size(...)
 * 
 * Proposals implemented in cxxomfort as of July 2015:
 * 
 * n3824 - make_array (for c++03)
 * n3928 - static_assert without message
 *
 */

/**
 * @page cxx03-backports
 * @brief Features that are backported to C++03.
 */

/**
 * @page cxx11-backports
 * @brief Features that are backported to C++11.
 */

#endif








|
>













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













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
#include "config.hpp"

//
// Main Features
//
// (pending minor reorganization as of v0.49)
#include "base.hpp"
#include "algorithm.hpp" // <algorithm> additions (copy_if, minmax, etc...)
#include "cstdint.hpp" // <cstdint> wrapper (integer types)
#include "functional.hpp" // <functional> additions (transparent functors, etc)
#include "limits.hpp" // compile-time integral limits
#include "memory.hpp" // <memory> additions (pointer_traits, alignof, unique_ptr, etc...)
#include "util/type_traits.hpp" // basic type_traits
#include "impl/regex-esc.hpp" // CXXO_R for raw regex patterns
#include "utility.hpp" // declval, exchange, pair...
#include "string.hpp" // string function helpers (eg.: to_string)
#include "type_traits.hpp" // common_type, decay, is_literal, is_null_pointer, ...
#include "library.hpp" // cxxomfort library features
#include "sequences.hpp" // sequence helpers, seq_<T>()
#include "using.hpp"


























































/**
 * @page cxx03-backports
 * @brief Features that are backported to C++03.
 */

/**
 * @page cxx11-backports
 * @brief Features that are backported to C++11.
 */

#endif

Changes to cxxomfort/cxxomfort/extras/array_ref.hpp.

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
 * 
* For documentation see @link Features/Extras @endlink .
* 
* Reflection header: experimental/array_ref
* 
**/

#if (defined(CXXOMFORT_NOTICES))
    #pragma message CXXO_NOTICE("enabled array_ref<T> implementation")
#endif

#include <cxxomfort/base.hpp>
#include <iterator>
#include <stdexcept>
#include <vector>
#include <array>
#include <valarray>
#include <cxxomfort/library/fixed_vector.hpp>
#include <cxxomfort/extras/dynarray.hpp>








namespace cxxomfort {
namespace extras {
namespace array_ref {

/**
 * @brief Array view for sequences, from n3334







<
<
<
<








>
>
>
>
>
>
>







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
 * 
* For documentation see @link Features/Extras @endlink .
* 
* Reflection header: experimental/array_ref
* 
**/





#include <cxxomfort/base.hpp>
#include <iterator>
#include <stdexcept>
#include <vector>
#include <array>
#include <valarray>
#include <cxxomfort/library/fixed_vector.hpp>
#include <cxxomfort/extras/dynarray.hpp>

#define CXXOMFORT_IMPLEMENTS_n3334 CXXO_LIBRARY()

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


namespace cxxomfort {
namespace extras {
namespace array_ref {

/**
 * @brief Array view for sequences, from n3334

Changes to cxxomfort/cxxomfort/extras/auto.hpp.

19
20
21
22
23
24
25




26
27
28
29
30
31
32
/**
 * @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>





//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)







>
>
>
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * @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)

Changes to cxxomfort/cxxomfort/extras/dynarray.hpp.

25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44

#include <cxxomfort/base.hpp>
#include <cxxomfort/sequences.hpp> // is_iterator
#include <iterator>
#include <algorithm>
#include <stdexcept>
#include <memory>


//
// using dynarray
//
#if (defined(CXXOMFORT_NOTICES))
    #pragma message CXXO_NOTICE("enabled 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







>





|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

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

//
// 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

Added cxxomfort/cxxomfort/extras/observer_ptr.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
#ifndef CXXOMFORT_EXTRAS_OBSERVER_PTR_HPP
#define CXXOMFORT_EXTRAS_OBSERVER_PTR_HPP
/**
 * @file cxxomfort/extras/observer_ptr.hpp
 * @brief Implements observer_ptr proposal (n3840)
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 * 
* For documentation see @link Features/Extras @endlink .
* 
* Reflection header: experimental/memory (to be mapped in cstd)
* 
**/

#include <cxxomfort/config.hpp>
#define CXXOMFORT_IMPLEMENTS_n3840 CXXO_BACKPORT()
#define CXXOMFORT_IMPLEMENTS_n4282 CXXO_BACKPORT()
#include <memory>
#include <functional> // std::hash

#if (defined(CXXOMFORT_NOTICES))
    #pragma message CXXO_NOTICE("enabled extras: observer_ptr<T> from TR2")
#endif

namespace cxxomfort {
namespace extras {
namespace observer_ptr {

/**
 * @brief observer_ptr - the world's dumbest smart pointer
 * 
 * @c observer_ptr  is a simple "pointer wrapper" type that manages a 
 * non-owning pointer. No further "intelligence" is added to the wrapper's 
 * behaviour. It is added to C++17 as an "experimental".
 * 
 * @sa n3840
 * 
 */
template <typename W>
struct observer_ptr {
    typedef W element_type;
    typedef W* pointer;
    typedef W& reference;
    typedef observer_ptr<W> this_type;
    
    
    CXXO_CONSTEXPR observer_ptr () CXXO_NOEXCEPT  //!< def-ctor
    : w(nullptr) {}
#if (CXXOMFORT_CXX_STD < 2011)
    CXXO_CONSTEXPR observer_ptr (observer_ptr const& r) CXXO_NOEXCEPT : w(r.w) {}
#else
    CXXO_CONSTEXPR observer_ptr (observer_ptr const& r) CXXO_NOEXCEPT = default;
#endif

    CXXO_COMPILER_ observer_ptr (std::nullptr_t) CXXO_NOEXCEPT //!< nullptr-ctor
    : w(nullptr) {}
    CXXO_CONSTEXPR observer_ptr (pointer r) CXXO_NOEXCEPT  //!< pointer-ctor
    : w(r) {}
    
    // interfaces defined in cppreference
    CXXO_CONSTEXPR pointer get () CXXO_NOEXCEPT { return w; }
    CXXO_CONSTEXPR pointer const get () const CXXO_NOEXCEPT { return w; }
    
    //! resets to pointer 'p', or @c nullptr .
    CXXO_CONSTEXPR void       reset (pointer r = nullptr) CXXO_NOEXCEPT { w=r; }
    //! resets to @c nullptr .
    CXXO_CONSTEXPR pointer    release ()  CXXO_NOEXCEPT { pointer r=w; this->reset(); return r; }
    
    CXXO_CONSTEXPR void       swap (observer_ptr& r) CXXO_NOEXCEPT {
        using std::swap;
        swap(this->w, r.w);
    }

    // extra interfaces
    //! checks if observer is set.
    CXXO_CONSTEXPR bool       is_set () const CXXO_NOEXCEPT { return !(w==nullptr); }

    //! conversion to @c pointer  type (explicit).
    CXXO_EXPLICIT_OPERATOR(pointer) const CXXO_NOEXCEPT { return this->get(); }
    //! conversion to @c bool  type (explicit).
    CXXO_EXPLICIT_OPERATOR(bool) const CXXO_NOEXCEPT { return this->is_set(); }

    reference       operator* () const CXXO_NOEXCEPT { return *w; }
    pointer         operator-> () const CXXO_NOEXCEPT { return w; }


    CXXO_CONSTEXPR friend operator== (observer_ptr const& l, observer_ptr const& r) CXXO_NOEXCEPT {
        return l.w == r.w; 
    }
    

    private:
    W* w;
};

//! makes an observer_ptr
template <typename W>
observer_ptr<W> make_observer (W* w) CXXO_NOEXCEPT {
    return observer_ptr<W> (w);
}


template <typename W>
bool operator!= (observer_ptr<W> const& l, observer_ptr<W> const& r) CXXO_NOEXCEPT {
    return !(l==r);
}

template <typename W>
bool operator< (observer_ptr<W> const& l, observer_ptr<W> const& r) CXXO_NOEXCEPT {
    return (l.get()<r.get());
}

template <typename W>
bool operator<= (observer_ptr<W> const& l, observer_ptr<W> const& r) CXXO_NOEXCEPT {
    return !(r<l);
}

template <typename W>
bool operator> (observer_ptr<W> const& l, observer_ptr<W> const& r) CXXO_NOEXCEPT {
    return (r<l);
}

template <typename W>
bool operator>= (observer_ptr<W> const& l, observer_ptr<W> const& r) CXXO_NOEXCEPT {
    return !(l<r);
}

} // observer_ptr
} // extras
} // cxxomfort

#endif

Changes to cxxomfort/cxxomfort/extras/optional-impl.hpp.

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
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) : /*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)
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






} //detail::

// Wrapper for nullable types
template <typename T, typename>
class optional {
    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;

    
    //! Default constructor (@c noexcept ; trivial if @p T is a fundamental type)
    CXXO_CONSTEXPR optional () CXXO_NOEXCEPT
    : _engaged(false), _storage(detail::trivial_init) {}

    //! Copy constructor (defaulted-trivial if @p T is a fundamental type)
    optional (optional 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 (nullopt_t) CXXO_NOEXCEPT
    : _storage(detail::trivial_init), _engaged(false) {}

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

    //
    // emplace constructor
    //
#if (CXXOMFORT_CXX_STD >= 2011) || defined(DOXYGEN_DOCS)
    //! Emplace constructor (up to 5 arguments in C++03 mode)
    template <typename... Args>
    optional (emplace_t, Args&&... args)
    : _engaged(true), _storage(detail::trivial_init) {
        new (std::addressof(_storage)) value_type(std::forward<Args>(args)...);
    }
#else
    optional (emplace_t)


    : _engaged(true), _storage(detail::trivial_init) {
        new (std::addressof(_storage)) value_type() ;
    }


    template <typename A1>
    optional (emplace_t, CXXO_FWD_REF(A1) a1)
    : _engaged(true), _storage(detail::trivial_init) {
        new (std::addressof(_storage)) value_type(a1) ;
    }

    template <typename A1, typename A2>
    optional (emplace_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) ;
    }

    template <typename A1, typename A2, typename A3>
    optional (emplace_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) ;
    }

    template <typename A1, typename A2, typename A3, typename A4>
    optional (emplace_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

#if (CXXOMFORT_CXX_STD >= 2011) || defined(DOXYGEN_DOCS)
    // Move constructor (defaulted)
    //optional (optional&&) = default;
#endif
    //! Destructor (trivial if @p T is a fundamental type)
    ~optional () { this->destruct(); }


    //! Assignment (@c noexcept  and trivial if @p T is a fundamental type)
    optional& operator= (optional 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& operator= (nullopt_t) CXXO_NOEXCEPT {
        destruct();
        _engaged= false;
        return *this;
    }
    //! Engaging assignment (trivial if @p T is a fundamental type)
    optional& operator= (T const& t) {
        if (!_engaged) {
            new (std::addressof(_storage)) value_type(t);
            _engaged= true;
        }
        return *this;
    }

    //! Check engagement state of object.
    CXXO_CONSTEXPR bool  engaged () 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();
    }
    //! @overloads value
    T&              value () {
        if (!_engaged) throw bad_optional_access("disengaged call to value() non-const");
        return *cast_it();
    }






















    //! Swap contents with another object.
    void swap (optional& 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());
        }
        
    }

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

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





    





















    private:

    storage_type    _storage;
    bool            _engaged;

    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();
    }


};

//
// implementation details for optional<T>
//




//
// 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<T, typename std::enable_if<std::is_fundamental<T>::value>::type > {
    private:
    typedef T       storage_type;
    public:
    typedef T       value_type;


    CXXO_CONSTEXPR optional () CXXO_NOEXCEPT
    : _engaged(false) {}
    // trivially copyable
    CXXOMFORT_CXX11_CODE(optional(optional const&) = default,);






    CXXO_CONSTEXPR optional (nullopt_t) CXXO_NOEXCEPT
    : _engaged(false) {}
    CXXO_CONSTEXPR optional (T const& t) CXXO_NOEXCEPT

    : _engaged(true), _storage(t) {}
    // trivially destructible
    CXXOMFORT_CXX11_CODE(~optional() = default,);
    
    CXXO_CONSTEXPR bool engaged () const CXXO_NOEXCEPT { return _engaged; }
    
    CXXO_CONSTEXPR CXXO_EXPLICIT_OPERATOR(bool) () const CXXO_NOEXCEPT {
        return _engaged;
    }
    
    // trivially copy-assignable
    CXXOMFORT_CXX11_CODE(optional& operator=(optional const&) = default,);









    optional& operator= (nullopt_t) CXXO_NOEXCEPT {
        _engaged=false;
        return *this;
    }
    optional& operator= (T t) CXXO_NOEXCEPT {
        _engaged= true;
        _storage= t;
        return *this;
    }
    
    CXXO_CONSTEXPR T const& operator* () const {
        if (_engaged) return _storage; else throw bad_optional_access("call to operator*() const");
    }
    
    T& operator* () {
        if (_engaged) return _storage;
        throw bad_optional_access("call to operator*()");
    }
    
    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) throw bad_optional_access("call to value() non-const");
        return _storage;
    }



    // emplace constructions can only take one argument
    optional& emplace (T t) CXXO_NOEXCEPT {
        return (*this= t);
    }


    

    void swap (optional& o) CXXO_NOEXCEPT {

        std::swap(_engaged, o._engaged);
        std::swap(_storage, o._storage);
    }
    
    private:

    bool            _engaged;
    T               _storage;

};




//}
//}}


#endif







|







|











>
>
>
>
>
|


|
|


>



|

>


|



|





|



|




<
<
<
|
|

|




|
>
>



>
>

|



>

|



>

|



>

<
|
<



<


<
<
<
<

|

>

|






|





|







|
|
|
>
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|










|
|
|
|
>
|
<
<
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>


>













<
<
<
>

>
>








|


|

>
>
|


<
>
>
>
>
>
>
|

<
>


|








|
>
>
>
>
>
>
|
>
>
|



|





|
|


|
|
<







 







|
<


>
>

|
|

>
>
|
>
|
>





>


>

>

>
|
<
<

<

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
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;
    protected:
    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();
    }
    //! @overloads 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(); }
    //! @overloads 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;
    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

Changes to cxxomfort/cxxomfort/extras/optional-io.hpp.

1
2
3
4
5
6
7
8
9
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#ifndef LPP_BASE_OPTIONAL_IO_HPP
#define LPP_BASE_OPTIONAL_IO_HPP

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

namespace cxxomfort {
................................................................................
        }
    }
    return is;
}

template <typename T>
std::ostream& operator<< (std::ostream& os, optional<T> const& o) {
    if (o == nullopt) os<< io_optional_empty::value();
    else os<< *o;
    return os;
}

}
}
}


#endif
|
|







 







|
<









1
2
3
4
5
6
7
8
9
..
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 {
................................................................................
        }
    }
    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

Changes to cxxomfort/cxxomfort/extras/optional.hpp.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
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
...
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
...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
 *
 * 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 "../config.hpp"
#include "../base/static_assert.hpp"
#include "../base/explicit_cast.hpp"
#include <type_traits>
#include <cassert>
#include <stdexcept>
#include <iostream>

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

namespace cxxomfort {
namespace extras {
namespace optional {

/**
................................................................................
 * 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, typename Enabler=void> class optional;
//template <typename T> 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 {} nullopt = {};




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


//! 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) {}
................................................................................

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

#include "optional-impl.hpp"

//
// utility typedefs
// (cxxomfort additions)
//
typedef optional<int> opt_int_t;
typedef optional<unsigned int> opt_uint_t;
typedef optional<size_t> opt_size_t;


// ----

//
// is_optional
//


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

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


//






































































// nonmember get
//


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

template <typename T>
inline T const& get (optional<T> const& o) { return o.operator*(); }

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->();
}


//
// make_optional
//
//template <typename T>
//inline optional<T> make_optional (T const& t) { return optional<T>(t); }

//template <typename T>
//inline optional<T> make_optional (nullopt_t const&) { return optional<T>(nullopt); }

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


/*
template <typename T>
optional<T>& optional<T>::operator= (optional<T> const& rhs) {
    if (!rhs.initialized()) this->assign(nullopt);
    else this->assign(*rhs);
    return *this;
}


#if defined(CXXOMFORT_CXX11_MODE)
template <typename T>
template <typename... Args>
optional<T>& optional<T>::emplace (Args&&... args) {
    this->assign(nullopt);
    this->initialize(std::forward<Args>(args)...);
    return *this;
}
#else
template <typename T>
optional<T>& optional<T>::emplace () {
    this->assign(nullopt);
    this->initialize();
    return *this;
}

template <typename T>
template <typename Arg1>
optional<T>& optional<T>::emplace (CXXO_FWD_REF(Arg1) a1) {
    this->assign(nullopt);
    this->initialize(std::forward<Arg1>(a1));
    return *this;
}

template <typename T>
template <typename Arg1, typename Arg2>
optional<T>& optional<T>::emplace (CXXO_FWD_REF(Arg1) a1, CXXO_FWD_REF(Arg2) a2) {
    this->assign(nullopt);
    this->initialize(std::forward<Arg1>(a1), std::forward<Arg2>(a2));
    return *this;
}

template <typename T>
template <typename Arg1, typename Arg2, typename Arg3>
optional<T>& optional<T>::emplace (CXXO_FWD_REF(Arg1) a1, CXXO_FWD_REF(Arg2) a2, CXXO_FWD_REF(Arg3) a3) {
    this->assign(nullopt);
    this->initialize(std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3));
    return *this;
}

#endif

template <typename T>
void  optional<T>::swap (optional<T>& R) {
    if (*this != nullopt && R != nullopt ) {
        this->assign(R.get());
        R.reset();
    }
    else if (*this != nullopt && R == nullopt) {
        R.assign(this->operator*());
        this->reset();
    }
    else if (*this != nullopt && R == nullopt) {
        using std::swap;
        swap(this->operator*(), R.operator*());
    }
}
*/

} // 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:
................................................................................
        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








|
|







|







 







|

|


|

|


|


>
|
<










|
>
>
>


|







 







<
<
<
<
<
<
<
<
<



|
|
<
<
>
|





>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>


>


>







 







<
<
<
<
<
<
<
<
<
<
<
|
<






|
|
|
|
<
<
|

<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


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










|







 







|










9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
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
...
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
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
 *
 * 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 {

/**
................................................................................
 * 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) {}
................................................................................

//
// 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

#if (CXXOMFORT_CXX_STD >= 2011 || (CXXOMFORT_CXX_EMULATION >= 2011 && CXXO_COMPILER_SUPPORT_explicit_operator>0))
    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:
................................................................................
        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

Changes to cxxomfort/cxxomfort/functional.hpp.

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
 * Interfaces defined in this file:
 *
 * * bit_and, bit_or, bit_not as per C++14.
 * * transparent plus, minus, multiplies, divides, modulus as per C++14.
 *
 */

#include "./base.hpp"
#include CXXO_INCLUDE_SYS(functional)

// fix missing bit_and, bit_or, bit_xor in MSVC 2008
#if (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_MSC && CXXOMFORT_COMPILER_VERSION <= 150)


namespace std {

/**


 * @addtogroup functional
 * @{
 */

//! @ref cxx03-backports
template <typename T> struct bit_and {
    T operator() (T const& a, T const& b) const { return a&b; }
};

//! @ref cxx03-backports
template <typename T> struct bit_or {
    T operator() (T const& a, T const& b) const { return a|b; }
};

//! @ref cxx03-backports
template <typename T> struct bit_xor {
    T operator() (T const& a, T const& b) const { return a^b; }
};

} // namespace std

#endif // msvc

/**
 * @addtogroup functional
 * @{
 */









|


|
|
>

<
<
<
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|







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
 * Interfaces defined in this file:
 *
 * * bit_and, bit_or, bit_not as per C++14.
 * * transparent plus, minus, multiplies, divides, modulus as per C++14.
 *
 */

#include <cxxomfort/base.hpp>
#include CXXO_INCLUDE_SYS(functional)

#if (defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1))
    #pragma message CXXO_NOTICE("enabled <functional> support.")
#endif




// The bit_and and sibling functors from <functional> are missing in MSVC 2008
#if (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_MSC && CXXOMFORT_COMPILER_VERSION <= 150)
    #include "impl/03-functional_bit.hpp"




















#endif

/**
 * @addtogroup functional
 * @{
 */


Added cxxomfort/cxxomfort/impl/03-functional_bit.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
#ifndef CXXOMFORT_IMPL_STD_BIT_HPP
#define CXXOMFORT_IMPL_STD_BIT_HPP

#include "./base.hpp"
#include CXXO_INCLUDE_SYS(functional)

// fix missing bit_and, bit_or, bit_xor in MSVC 2008
#if (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_MSC && CXXOMFORT_COMPILER_VERSION <= 150)

namespace std {

/**
 * @addtogroup functional
 * @{
 */

//! @ref cxx03-backports
template <typename T> struct bit_and {
    T operator() (T const& a, T const& b) const { return a&b; }
};

//! @ref cxx03-backports
template <typename T> struct bit_or {
    T operator() (T const& a, T const& b) const { return a|b; }
};

//! @ref cxx03-backports
template <typename T> struct bit_xor {
    T operator() (T const& a, T const& b) const { return a^b; }
};

} // namespace std

#endif // msvc

#endif

Added cxxomfort/cxxomfort/impl/03-random_renames.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
#ifndef CXXOMFORT_IMPL_RANDOM_RENAMES_HPP
#define CXXOMFORT_IMPL_RANDOM_RENAMES_HPP

#include "./base.hpp"
#include CXXO_INCLUDE_SYS(random)

// fix renamed functors in <random> between C++03 TR1 and C++11
#if (CXXOMFORT_CXX_STD < 2011)
namespace std {
namespace tr1 {

// These are only "good enough to work" fixes.

template <typename II, II _w, II _s, II _r>
class subtract_with_carry_engine 
: public subtract_with_carry<II,_w,_s,_r> {
    public:
    typedef typename subtract_with_carry<II,_w,_s,_r>::result_type result_type;
    subtract_with_carry_engine(result_type s=0) 
    : subtract_with_carry<II,_w,_s,_r>(s) {}
};

typedef subtract_with_carry_engine<uint_fast32_t, 24,10,24> ranlux24_base;

template <typename II>
class uniform_int_distribution
: public uniform_int<II> {
    public:
    uniform_int_distribution(II a, II b)
    : uniform_int<II>(a,b) {}
};

template <typename Real>
class uniform_real_distribution
: public uniform_real<Real> {
    public:
    uniform_real_distribution(Real a, Real b)
    : uniform_real<Real>(a,b) {}
};


} // namespace tr1
} // namespace std

#endif // fix

#endif

Changes to cxxomfort/cxxomfort/impl/11-is_xxx_of.hpp.

1
2




3
4
5
6
7
8
9
..
47
48
49
50
51
52
53



54
55
56


57
58
59
60
#ifndef CXXOMFORT_IMPL_IS_OF_HPP
#define CXXOMFORT_IMPL_IS_OF_HPP




/**
 * @file 11-is_xxx_of.hpp
 */
namespace cxxomfort {
namespace algorithm {

/**
................................................................................

} // cxxomfort::algo
} // cxxomfort

// These were added in c++11
#if (CXXOMFORT_CXX_STD < 2011)
namespace std {



    using ::cxxomfort::algorithm::all_of;
    using ::cxxomfort::algorithm::any_of;
    using ::cxxomfort::algorithm::none_of;


}
#endif // c++11
#endif



>
>
>
>







 







>
>
>



>
>




1
2
3
4
5
6
7
8
9
10
11
12
13
..
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#ifndef CXXOMFORT_IMPL_IS_OF_HPP
#define CXXOMFORT_IMPL_IS_OF_HPP

#include <cxxomfort/config.hpp>
#define CXXOMFORT_IMPLEMENTS_n2569 CXXO_BACKPORT()

/**
 * @file 11-is_xxx_of.hpp
 */
namespace cxxomfort {
namespace algorithm {

/**
................................................................................

} // cxxomfort::algo
} // cxxomfort

// These were added in c++11
#if (CXXOMFORT_CXX_STD < 2011)
namespace std {
#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC && CXXOMFORT_COMPILER_VERSION >=404 && CXXOMFORT_COMPILER_VERSION <= 406 && CXXOMFORT_CXX_EMULATION==2011 )
    // GCC already has defined these in 4.4-4.6 c++0x mode
#else
    using ::cxxomfort::algorithm::all_of;
    using ::cxxomfort::algorithm::any_of;
    using ::cxxomfort::algorithm::none_of;
#endif

}
#endif // c++11
#endif

Changes to cxxomfort/cxxomfort/impl/11-permutations.hpp.

94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111

} // cxxomfort::algo
} // cxxomfort

// These were added in c++11
#if (CXXOMFORT_CXX_STD < 2011)
namespace std {
    using ::cxxomfort::algorithm::is_permutation;
// [next,prev]_permutation already present in GCC >= 4.4 as an extension
#if (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_GCC && CXXOMFORT_COMPILER_VERSION < 404)

    using ::cxxomfort::algorithm::prev_permutation;
    using ::cxxomfort::algorithm::next_permutation;
#endif

}
#endif // c++11

#endif







<


>








94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110
111

} // cxxomfort::algo
} // cxxomfort

// These were added in c++11
#if (CXXOMFORT_CXX_STD < 2011)
namespace std {

// [next,prev]_permutation already present in GCC >= 4.4 as an extension
#if (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_GCC && CXXOMFORT_COMPILER_VERSION < 404)
    using ::cxxomfort::algorithm::is_permutation;
    using ::cxxomfort::algorithm::prev_permutation;
    using ::cxxomfort::algorithm::next_permutation;
#endif

}
#endif // c++11

#endif

Changes to cxxomfort/cxxomfort/impl/11-to_string.hpp.

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
...
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
...
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
#else
    #define CXXOMFORT_USING_to_string
#endif

#if defined(CXXOMFORT_USING_to_string)

#if (defined(CXXOMFORT_NOTICES))

#pragma message CXXO_NOTICE("enabled to_string helper.")

#endif

#define CXXO_INTEGERDIGITS(T) std::numeric_limits< T >::digits10 + 3
#define CXXO_FLOATDIGITS(T) std::numeric_limits< T >::digits10 + 8

//
// MSVC <= 2010 is missing strtoll, strtoull definitions, but has the 
// functions proper under other names
//

#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_MSC \
    && CXXOMFORT_COMPILER_VERSION >= 130 && CXXOMFORT_COMPILER_VERSION <= 160)
//namespace std {
    static inline unsigned long long strtoull (const char* np, char ** ep, int b=10) {
        return _strtoui64(np,ep,b);
    }
    static inline signed long long strtoll (const char* np, char ** ep, int b=10) {
        return _strtoi64(np,ep,b);
    }
//}

#endif // MSVC fix






namespace cxxomfort {
namespace string {

namespace detail_string {

template <typename T> struct printfmask {};
................................................................................

    size_t* _p;
    const int _b;
    convertfn _pfn;
};


} //cxxomfort::detail


/**
 * @ingroup string
 * @{
 */

static inline std::string to_string (unsigned short u) {
    return detail_string::stringexpr(u);
}
//! @overloads to_string
static inline std::string to_string (unsigned long u) {
    return detail_string::stringexpr(u);
}
//! @overloads to_string
static inline std::string to_string (unsigned long long u) {
    return detail_string::stringexpr(u);
}




//! @overloads to_string
static inline std::string to_string (unsigned int u) {
    return detail_string::stringexpr(u);
}

//! @overloads to_string
static inline std::string to_string (short i) {
    return detail_string::stringexpr(i);
}
//! @overloads to_string
static inline std::string to_string (long i) {
    return detail_string::stringexpr(i);
}
//! @overloads to_string
static inline std::string to_string (long long i) {
    return detail_string::stringexpr(i);
}
//! @overloads to_string
static inline std::string to_string (int i) {
    return detail_string::stringexpr(i);
}

//! @overloads to_string
static inline std::string to_string (float i) {
    return detail_string::stringexpr(i);
}

//! @overloads to_string
static inline std::string to_string (double i) {
    return detail_string::stringexpr(i);
}

//! @overloads to_string
static inline std::string to_string (long double i) {
    return detail_string::stringexpr(i);
}

/*
std::wstring to_wstring (unsigned int i) {
    return detail::stringexpr(i);
}

std::wstring to_wstring (int i) {
    return detail::stringexpr(i);
................................................................................
    using ::cxxomfort::string::to_string;

    using ::cxxomfort::string::stoul;
    using ::cxxomfort::string::stol;
    using ::cxxomfort::string::stoull;
    using ::cxxomfort::string::stoll;
}
#elif (CXXOMFORT_CXX11_EMULATION>0)
namespace std {
    // GCC already brings those names
    #if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC)
    // MSC brings some of them
    #elif (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_MSC)





    using ::cxxomfort::string::to_string;
    // MSVC 2010 already has stol, stoul, but lacks the long long versions
        #if (CXXOMFORT_COMPILER_VERSION < 160)
        using ::cxxomfort::string::stol;
        using ::cxxomfort::string::stoul;

        #endif
    using ::cxxomfort::string::stoll;
    using ::cxxomfort::string::stoull;
    #endif
}
#endif // (c++11)

#endif

#endif







>
|
>









<












>
>
>
>
>







 







|











|
|





>
>
>
>




<









|



|
|

<




<





<
<
<
<
<







 







|





>
>
>
>
>
|

|


>










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
...
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
...
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
#else
    #define CXXOMFORT_USING_to_string
#endif

#if defined(CXXOMFORT_USING_to_string)

#if (defined(CXXOMFORT_NOTICES))
    #if (CXXOMFORT_NOTICES > 1)
    #pragma message CXXO_NOTICE("enabled to_string helper.")
    #endif
#endif

#define CXXO_INTEGERDIGITS(T) std::numeric_limits< T >::digits10 + 3
#define CXXO_FLOATDIGITS(T) std::numeric_limits< T >::digits10 + 8

//
// MSVC <= 2010 is missing strtoll, strtoull definitions, but has the 
// functions proper under other names
//

#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_MSC \
    && CXXOMFORT_COMPILER_VERSION >= 130 && CXXOMFORT_COMPILER_VERSION <= 160)
//namespace std {
    static inline unsigned long long strtoull (const char* np, char ** ep, int b=10) {
        return _strtoui64(np,ep,b);
    }
    static inline signed long long strtoll (const char* np, char ** ep, int b=10) {
        return _strtoi64(np,ep,b);
    }
//}

#endif // MSVC fix

//
// MSVC 2010 implements incorrect to_string, with only three overloads
// https://stackoverflow.com/questions/10664699/stdto-string-more-than-instance-of-overloaded-function-matches-the-argument
//

namespace cxxomfort {
namespace string {

namespace detail_string {

template <typename T> struct printfmask {};
................................................................................

    size_t* _p;
    const int _b;
    convertfn _pfn;
};


} //cxxomfort::string::detail_string


/**
 * @ingroup string
 * @{
 */

static inline std::string to_string (unsigned short u) {
    return detail_string::stringexpr(u);
}
//! @overloads to_string
static inline std::string to_string (long long i) {
    return detail_string::stringexpr(i);
}
//! @overloads to_string
static inline std::string to_string (unsigned long long u) {
    return detail_string::stringexpr(u);
}
//! @overloads to_string
static inline std::string to_string (long double i) {
    return detail_string::stringexpr(i);
}
//! @overloads to_string
static inline std::string to_string (unsigned int u) {
    return detail_string::stringexpr(u);
}

//! @overloads to_string
static inline std::string to_string (short i) {
    return detail_string::stringexpr(i);
}
//! @overloads to_string
static inline std::string to_string (long i) {
    return detail_string::stringexpr(i);
}
//! @overloads to_string
static inline std::string to_string (int i) {
    return detail_string::stringexpr(i);
}
//! @overloads to_string
static inline std::string to_string (unsigned long u) {
    return detail_string::stringexpr(u);
}

//! @overloads to_string
static inline std::string to_string (float i) {
    return detail_string::stringexpr(i);
}

//! @overloads to_string
static inline std::string to_string (double i) {
    return detail_string::stringexpr(i);
}






/*
std::wstring to_wstring (unsigned int i) {
    return detail::stringexpr(i);
}

std::wstring to_wstring (int i) {
    return detail::stringexpr(i);
................................................................................
    using ::cxxomfort::string::to_string;

    using ::cxxomfort::string::stoul;
    using ::cxxomfort::string::stol;
    using ::cxxomfort::string::stoull;
    using ::cxxomfort::string::stoll;
}
#elif (CXXOMFORT_CXX_EMULATION>0)
namespace std {
    // GCC already brings those names
    #if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC)
    // MSC brings some of them
    #elif (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_MSC)
        #if (CXXOMFORT_COMPILER_VERSION==160)
        // MSVC 2010 has failing overloads for to_string
            #if (CXXOMFORT_NOTICES > 2)
                #pragma message CXXO_NOTICE("adding missing overloads to to_string")
            #endif
        using ::cxxomfort::string::to_string;
    // MSVC 2010 already has stol, stoul, but lacks the long long versions
        #elif (CXXOMFORT_COMPILER_VERSION < 160)
        using ::cxxomfort::string::stol;
        using ::cxxomfort::string::stoul;
        using ::cxxomfort::string::to_string;
        #endif
    using ::cxxomfort::string::stoll;
    using ::cxxomfort::string::stoull;
    #endif
}
#endif // (c++11)

#endif

#endif

Changes to cxxomfort/cxxomfort/impl/14-functional-transparent.hpp.

21
22
23
24
25
26
27


28
29
30
31
32
33
34
...
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
 * * @c std::bit_or<void>
 * * @c std::bit_xor<void>
 * 
 */


#include <cxxomfort/config.hpp>


#include CXXO_INCLUDE_SYS(functional)
// <functional> needs to be #included for this to make any sense
#if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1)
#pragma message CXXO_NOTICE("enabled <functional> transparent functors")
#endif

#include <type_traits> // common_type
................................................................................
// (because no decltype), so we assume that heterogeneous functors 
// return homogeneously to the left (aka: they return the type of 1st operand).

    #define LPP_SPEC_FUNCTIONAL_VOID(Op,Sym) \
template<> struct Op <void> :   \
std:: Op< int> {    \
    template <typename T1, typename T2>     \

    inline typename std::remove_reference<T1>::type operator() (T1 const& a, T2 const& b) const { return a Sym b; } \
    template <typename T> struct result { typedef T type; }; \
    static const bool is_transparent = true;  \
}; \
template <typename T1, typename T2> struct Op<void>:: result< Op<void>(T1,T2) > { \
    typedef T1 type; \
}; \


#else

    #define LPP_SPEC_FUNCTIONAL_VOID(Op,Sym) \
template<> struct Op <void> { \
    template <typename T1, typename T2>  \
    inline typename std::common_type<T1,T2>::type  \
    operator() (T1 const& a, T2 const& b) const { return a Sym b; }  \
    template <typename T> struct result { typedef void type; };  \
    static const bool is_transparent = true;  \
}; \
template <typename T1, typename T2> struct Op<void>:: result< Op<void>(T1,T2) > { \
    typedef typename std::common_type<T1,T2>::type type; \
}; \







>
>







 







>
|













|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
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
 * * @c std::bit_or<void>
 * * @c std::bit_xor<void>
 * 
 */


#include <cxxomfort/config.hpp>
#define CXXOMFORT_IMPLEMENTS_n3431 CXXO_BACKPORT()

#include CXXO_INCLUDE_SYS(functional)
// <functional> needs to be #included for this to make any sense
#if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1)
#pragma message CXXO_NOTICE("enabled <functional> transparent functors")
#endif

#include <type_traits> // common_type
................................................................................
// (because no decltype), so we assume that heterogeneous functors 
// return homogeneously to the left (aka: they return the type of 1st operand).

    #define LPP_SPEC_FUNCTIONAL_VOID(Op,Sym) \
template<> struct Op <void> :   \
std:: Op< int> {    \
    template <typename T1, typename T2>     \
    inline typename \
    std::remove_reference<T1>::type operator() (T1 const& a, T2 const& b) const { return a Sym b; } \
    template <typename T> struct result { typedef T type; }; \
    static const bool is_transparent = true;  \
}; \
template <typename T1, typename T2> struct Op<void>:: result< Op<void>(T1,T2) > { \
    typedef T1 type; \
}; \


#else

    #define LPP_SPEC_FUNCTIONAL_VOID(Op,Sym) \
template<> struct Op <void> { \
    template <typename T1, typename T2>  \
    decltype( std::declval<T1>() Sym std::declval<T2>()  )  \
    operator() (T1 const& a, T2 const& b) const { return a Sym b; }  \
    template <typename T> struct result { typedef void type; };  \
    static const bool is_transparent = true;  \
}; \
template <typename T1, typename T2> struct Op<void>:: result< Op<void>(T1,T2) > { \
    typedef typename std::common_type<T1,T2>::type type; \
}; \

Changes to cxxomfort/cxxomfort/impl/14-integer_sequence.hpp.

1
2


3



4
5
6
7
8
9
10
..
93
94
95
96
97
98
99

100
101
102
#ifndef CXXOMFORT_IMPL_14_INTEGER_SEQUENCE_HPP
#define CXXOMFORT_IMPL_14_INTEGER_SEQUENCE_HPP






// room here for a possible c++03 implementation? I wish.
#if (CXXOMFORT_CXX_STD < 2011)


#elif (CXXOMFORT_CXX_STD == 2011 || (CXXOMFORT_CXX_EMULATION==2011 && CXXO_COMPILER_SUPPORT_variadic))

namespace cxxomfort {
................................................................................
    using cxxomfort::make_integer_sequence;
    using cxxomfort::make_index_sequence;

} // namespace std

#endif // c++11


#endif




>
>

>
>
>







 







>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
98
99
100
101
102
103
104
105
106
107
108
#ifndef CXXOMFORT_IMPL_14_INTEGER_SEQUENCE_HPP
#define CXXOMFORT_IMPL_14_INTEGER_SEQUENCE_HPP
#include <cxxomfort/config.hpp>
#define CXXOMFORT_IMPLEMENTS_n3658 CXXO_BACKPORT()

#if (CXXOMFORT_CXX_STD >= 2014)
    // nothing to do
#else
// room here for a possible c++03 implementation? I wish.
#if (CXXOMFORT_CXX_STD < 2011)


#elif (CXXOMFORT_CXX_STD == 2011 || (CXXOMFORT_CXX_EMULATION==2011 && CXXO_COMPILER_SUPPORT_variadic))

namespace cxxomfort {
................................................................................
    using cxxomfort::make_integer_sequence;
    using cxxomfort::make_index_sequence;

} // namespace std

#endif // c++11

#endif // support
#endif


Changes to cxxomfort/cxxomfort/impl/14-tuple_get_type.hpp.

7
8
9
10
11
12
13







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
..
30
31
32
33
34
35
36


37
38
39
40
41
42

43
44
45
46










47
48
49
50
51
52
53
..
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
 * http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3584.html
 * 
 * Interfaces defined in this header:
 * 
 * * std::get <T> (std::tuple<...>)
 * 
 */








#if (defined(CXXOMFORT_NOTICES))
    #pragma message CXXO_NOTICE("enabled tuple get<type> implementation")
#endif

#include <cxxomfort/base.hpp>
#include <type_traits>
#include <tuple>

//#define CXXO_TI_STRI0(x) #x
//#define CXXO_TI_STRI(x) CXXO_TI_STRI0(x)

namespace cxxomfort {
namespace tuple {

................................................................................

/*
 * Check if an element of type T is already in Tuple, 
 * if so, returns its index
 */
template <typename C, int N, int M, typename Tuple>
struct tuple_element2index_helper {


    enum { value = 
    (std::is_same<C, typename std::tuple_element<N,Tuple>::type>::value
    ? N : tuple_element2index_helper<C,N+1,M,Tuple>::value
    ) 
    };
};


template <typename C, int N, typename Tuple>
struct tuple_element2index_helper<C,N,N,Tuple> {
    enum { value = N };










};

template <typename T1,typename T2>
struct tuple_element2index_helper_pair {
    enum { value= (0==std::is_same<T1,T2>::value) };
    static_assert (value, "Tuple get<type> interface for pair requires pair of distinct types");
};
................................................................................
#if (CXXOMFORT_CXX_STD >= 2014 || CXXOMFORT_CXX_EMULATION == 2014)
    // already available, do nothing
#elif (CXXOMFORT_CXX_STD == 2011 || (CXXO_COMPILER_SUPPORT_variadic && CXXO_COMPILER_SUPPORT_rvref) )

// three overloads as per cppreference

template <typename C, typename... Targs
, typename = std::enable_if< cxxomfort::tuple::tuple_index<C,std::tuple<Targs...> >::value> 
>
C&& get (std::tuple<Targs...>&& t) CXXO_NOEXCEPT {
    enum { N = cxxomfort::tuple::tuple_index<C, std::tuple<Targs...> >::value };
    return std::forward<C>(get<N>(t));
}

template <typename C, typename... Targs
, typename = std::enable_if< cxxomfort::tuple::tuple_index<C,std::tuple<Targs...> >::value> 
>
C const& get (std::tuple<Targs...> const& t) CXXO_NOEXCEPT {
    enum { N = cxxomfort::tuple::tuple_index<C, std::tuple<Targs...> >::value };
    return (get<N>(t));
}

template <typename C, typename... Targs
, typename = std::enable_if< cxxomfort::tuple::tuple_index<C,std::tuple<Targs...> >::value> 
>
C& get (std::tuple<Targs...> & t) CXXO_NOEXCEPT {
    enum { N = cxxomfort::tuple::tuple_index<C, std::tuple<Targs...> >::value };
    return (get<N>(t));
}

#else
// at this point, c++03

template <typename C, typename Tuple>
typename std::enable_if< cxxomfort::tuple::is_tuple<Tuple>::value,
    typename std::tuple_element< cxxomfort::tuple::tuple_index<C,Tuple>::value, Tuple>::type
>::type
const& get (Tuple const& t) {
    enum { N = cxxomfort::tuple::tuple_index<C,Tuple>::value }; 
    return get<N>(t);
}

template <typename C, typename Tuple>
typename std::enable_if< cxxomfort::tuple::is_tuple<Tuple>::value,
    typename std::tuple_element< cxxomfort::tuple::tuple_index<C,Tuple>::value, Tuple>::type&
>::type
get (Tuple& t) {
    enum { N = cxxomfort::tuple::tuple_index<C,Tuple>::value }; 
    return get<N>(t);
}








>
>
>
>
>
>
>





<
<
<







 







>
>






>



|
>
>
>
>
>
>
>
>
>
>







 







|
|






|







|










|








|







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
..
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
...
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
 * http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3584.html
 * 
 * Interfaces defined in this header:
 * 
 * * std::get <T> (std::tuple<...>)
 * 
 */

#include <cxxomfort/base.hpp>
#define CXXOMFORT_IMPLEMENTS_n3584 CXXO_EMULATION()
#define CXXOMFORT_IMPLEMENTS_n3670 CXXO_EMULATION()

#include <type_traits>
#include <tuple>

#if (defined(CXXOMFORT_NOTICES))
    #pragma message CXXO_NOTICE("enabled tuple get<type> implementation")
#endif





//#define CXXO_TI_STRI0(x) #x
//#define CXXO_TI_STRI(x) CXXO_TI_STRI0(x)

namespace cxxomfort {
namespace tuple {

................................................................................

/*
 * Check if an element of type T is already in Tuple, 
 * if so, returns its index
 */
template <typename C, int N, int M, typename Tuple>
struct tuple_element2index_helper {
    enum { rec = (0 <= N && N < M) };
    typedef typename std::enable_if<rec, bool>::type still_has_arguments_t;
    enum { value = 
    (std::is_same<C, typename std::tuple_element<N,Tuple>::type>::value
    ? N : tuple_element2index_helper<C,N+1,M,Tuple>::value
    ) 
    };
};


template <typename C, int N, typename Tuple>
struct tuple_element2index_helper<C,N,N,Tuple> {
    enum { value = -1 };
};

// this makes recursion stop, as the "value" needed to keep computing is not found.
template <typename C, int N, typename Tuple>
struct tuple_element2index_helper<C,-1,N,Tuple> {
};

// this *also* makes recursion stop, as the "value" needed to keep computing is not found.
template <typename C, int N, typename Tuple>
struct tuple_element2index_helper<C,-2,N,Tuple> {
};

template <typename T1,typename T2>
struct tuple_element2index_helper_pair {
    enum { value= (0==std::is_same<T1,T2>::value) };
    static_assert (value, "Tuple get<type> interface for pair requires pair of distinct types");
};
................................................................................
#if (CXXOMFORT_CXX_STD >= 2014 || CXXOMFORT_CXX_EMULATION == 2014)
    // already available, do nothing
#elif (CXXOMFORT_CXX_STD == 2011 || (CXXO_COMPILER_SUPPORT_variadic && CXXO_COMPILER_SUPPORT_rvref) )

// three overloads as per cppreference

template <typename C, typename... Targs
/* , typename = std::enable_if< cxxomfort::tuple::tuple_index<C,std::tuple<Targs...> >::value != -1 */
> 
C&& get (std::tuple<Targs...>&& t) CXXO_NOEXCEPT {
    enum { N = cxxomfort::tuple::tuple_index<C, std::tuple<Targs...> >::value };
    return std::forward<C>(get<N>(t));
}

template <typename C, typename... Targs
/* , typename = std::enable_if< cxxomfort::tuple::tuple_index<C,std::tuple<Targs...> >::value != -1  */
>
C const& get (std::tuple<Targs...> const& t) CXXO_NOEXCEPT {
    enum { N = cxxomfort::tuple::tuple_index<C, std::tuple<Targs...> >::value };
    return (get<N>(t));
}

template <typename C, typename... Targs
, typename = std::enable_if< cxxomfort::tuple::tuple_index<C,std::tuple<Targs...> >::value != -1> 
>
C& get (std::tuple<Targs...> & t) CXXO_NOEXCEPT {
    enum { N = cxxomfort::tuple::tuple_index<C, std::tuple<Targs...> >::value };
    return (get<N>(t));
}

#else
// at this point, c++03

template <typename C, typename Tuple>
typename std::enable_if< cxxomfort::tuple::is_tuple<Tuple>::value ,
    typename std::tuple_element< cxxomfort::tuple::tuple_index<C,Tuple>::value, Tuple>::type
>::type
const& get (Tuple const& t) {
    enum { N = cxxomfort::tuple::tuple_index<C,Tuple>::value }; 
    return get<N>(t);
}

template <typename C, typename Tuple>
typename std::enable_if< cxxomfort::tuple::is_tuple<Tuple>::value && (cxxomfort::tuple::tuple_index<C,Tuple>::value != -1), 
    typename std::tuple_element< cxxomfort::tuple::tuple_index<C,Tuple>::value, Tuple>::type&
>::type
get (Tuple& t) {
    enum { N = cxxomfort::tuple::tuple_index<C,Tuple>::value }; 
    return get<N>(t);
}

Changes to cxxomfort/cxxomfort/impl/17-void_t.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
..
56
57
58
59
60
61
62
63
64
65
#ifndef CXXOMFORT_IMPL_VOID_T_HPP
#define CXXOMFORT_IMPL_VOID_T_HPP
/**
 * @file impl/17-void_t.hpp
 * @brief Header file providing implementation of the "void_t" concept.
 * 
 * http://en.cppreference.com/w/cpp/types/void_t

 * 
 */

// Documentation only
#if defined (DOXYGEN_DOC)
namespace cxxomfort {
/**
 * @brief Maps a sequence of types to @c void .
 * @ingroup type_traits
 * @ref cxx03-backports
 * @ref cxx11-backports
 * @ref cxx14-backports
 */
template <typename Arguments...>
struct make_void { 
    typedef void type;
};

} // cxxomfort

#else // ~documentation


#if (CXXOMFORT_CXX_STD < 2017)

// void_t and make_void for c++03, c++11, c++14

namespace cxxomfort {
#if (CXXOMFORT_CXX_STD < 2011)
    //! @internal
    template <typename T0, typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void, typename T6=void, typename T7=void, typename T8=void, typename T9=void>
#else
    //! @internal
    template <typename... Types>
#endif
    struct make_void {
        typedef void type;
    };
................................................................................
using void_t = typename make_void<Ts...>::type;
}
#endif


#endif // c++17

#endif // documentation

#endif






|
>



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
>








|







 







<
<

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
..
41
42
43
44
45
46
47


48
#ifndef CXXOMFORT_IMPL_VOID_T_HPP
#define CXXOMFORT_IMPL_VOID_T_HPP
/**
 * @file impl/17-void_t.hpp
 * @brief Header file providing implementation of the "void_t" concept.
 * 
 * @sa http://en.cppreference.com/w/cpp/types/void_t
 * @sa n3911
 * 
 */
















#include <cxxomfort/config.hpp>


#define CXXOMFORT_IMPLEMENTS_n3911 CXXO_BACKPORT()

#if (CXXOMFORT_CXX_STD < 2017)

// void_t and make_void for c++03, c++11, c++14

namespace cxxomfort {
#if (CXXOMFORT_CXX_STD < 2011)
    //! @internal
    template <typename T0=void, typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void, typename T6=void, typename T7=void, typename T8=void, typename T9=void>
#else
    //! @internal
    template <typename... Types>
#endif
    struct make_void {
        typedef void type;
    };
................................................................................
using void_t = typename make_void<Ts...>::type;
}
#endif


#endif // c++17



#endif

Changes to cxxomfort/cxxomfort/impl/to_basic_string_cxx03.hpp.

309
310
311
312
313
314
315
316
317
// 3 arguments
template <typename T0, typename T1, typename T2>
std::string  to_string
(T0 const& t0, T1 const& t1, T2 const& t2) {
    return to_basic_string_defaults<char>(t0,t1,t2);
}

}
} // cxxomfort







|

309
310
311
312
313
314
315
316
317
// 3 arguments
template <typename T0, typename T1, typename T2>
std::string  to_string
(T0 const& t0, T1 const& t1, T2 const& t2) {
    return to_basic_string_defaults<char>(t0,t1,t2);
}

} // string
} // cxxomfort

Changes to cxxomfort/cxxomfort/library.hpp.

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

// extra algorithm variants (find_last_if, count_while, etc)
#include "library/algorithmfn.hpp"
// for (x:range) emulation
#include "library/foreach.hpp"
// object-like primitive wrapper for fundamentals (int, long, etc)
// #include "library/fundamental.hpp"


// initialization of containers and sequences
#include "library/i12n.hpp"
// extra iterator helpers (constant_iterator, etc)
#include "library/iteratorfn.hpp"
// fixed_vector - the oft sought for vector without resize
#include "library/fixed_vector.hpp"
// functional plus<> like complements for +=, -=, ...
#include "library/operatorit.hpp"
// local function emulation
#include "library/localfn.hpp"
// pair03 - movable pair type for C++03
#include "library/pair03.hpp"




// typename to string helpers - typeid_demangle, type_name
#include "library/type_name.hpp"

/*
 * is_pair
 */
namespace cxxomfort {







>
>




|
|


<
<


>
>
>
>







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

// extra algorithm variants (find_last_if, count_while, etc)
#include "library/algorithmfn.hpp"
// for (x:range) emulation
#include "library/foreach.hpp"
// object-like primitive wrapper for fundamentals (int, long, etc)
// #include "library/fundamental.hpp"
// fixed_vector - the oft sought for vector without resize
#include "library/fixed_vector.hpp"
// initialization of containers and sequences
#include "library/i12n.hpp"
// extra iterator helpers (constant_iterator, etc)
#include "library/iteratorfn.hpp"
// local function emulation
#include "library/localfn.hpp"
// functional plus<> like complements for +=, -=, ...
#include "library/operatorit.hpp"


// pair03 - movable pair type for C++03
#include "library/pair03.hpp"
// extra string extensions (join, trim, etc)
#include "library/stringfn.hpp"
// extra tuple extensions (tuple_pop, etc)
#include "library/tuplefn.hpp"
// typename to string helpers - typeid_demangle, type_name
#include "library/type_name.hpp"

/*
 * is_pair
 */
namespace cxxomfort {

Changes to cxxomfort/cxxomfort/library/algorithmfn.hpp.

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
        ++first;
    }
    return ret;
}

//! transform_inplace
template <typename FIter, typename F>
FIter transform_inplace (Fiter ini, Fiter fin, F f) {
    for (; ini != fin; ++ini) {
        *ini= f(*ini);
    }
    return ini;
}

//! transform elements up to n times







|







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
        ++first;
    }
    return ret;
}

//! transform_inplace
template <typename FIter, typename F>
FIter transform_inplace (FIter ini, FIter fin, F f) {
    for (; ini != fin; ++ini) {
        *ini= f(*ini);
    }
    return ini;
}

//! transform elements up to n times

Changes to cxxomfort/cxxomfort/library/foreach.hpp.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
..
37
38
39
40
41
42
43

44
45
46
47

48
49

50

51
52
53
54
55
56
57
 * "range for" expression, acting natively.
 *
 * @see http://www.artima.com/cppsource/foreach.html
 */

#include <cxxomfort/config.hpp> // c++11


#if 0

// GNU C++ < 4.6 doesn't support new foreach even in C++0x mode
/*
#elif (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_GCC)
    // GCC version
    #if (CXXOMFORT_COMPILER_VERSION < 405) || !(CXXOMFORT_CXX_EMULATION < 2011)
................................................................................
#endif


#endif
// compiler ID

#if (!defined(CXXOMFORT_USING_FOREACH_EMULATION))


    #define CXXO_FOREACH(VDecl,CDecl) for (VDecl : CDecl)
    // end c++11
#else


    #if defined(CXXOMFORT_NOTICES)

    #pragma message CXXO_NOTICE("enabled foreach iteration support.")

    #endif

#if defined(__GNUC__)
    #include "../impl/foreach_gcc.hpp"
#else
    #include "../impl/foreach_artima.hpp"
#endif







<







 







>




>


>
|
>







14
15
16
17
18
19
20

21
22
23
24
25
26
27
..
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
 * "range for" expression, acting natively.
 *
 * @see http://www.artima.com/cppsource/foreach.html
 */

#include <cxxomfort/config.hpp> // c++11


#if 0

// GNU C++ < 4.6 doesn't support new foreach even in C++0x mode
/*
#elif (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_GCC)
    // GCC version
    #if (CXXOMFORT_COMPILER_VERSION < 405) || !(CXXOMFORT_CXX_EMULATION < 2011)
................................................................................
#endif


#endif
// compiler ID

#if (!defined(CXXOMFORT_USING_FOREACH_EMULATION))
    #define CXXOMFORT_IMPLEMENTS_n2930 CXXO_REDIRECT_NATIVE()

    #define CXXO_FOREACH(VDecl,CDecl) for (VDecl : CDecl)
    // end c++11
#else
    #define CXXOMFORT_IMPLEMENTS_n2930 CXXO_EMULATION()

    #if defined(CXXOMFORT_NOTICES)
        #if (CXXOMFORT_NOTICES > 1)
        #pragma message CXXO_NOTICE("enabled foreach iteration support.")
        #endif
    #endif

#if defined(__GNUC__)
    #include "../impl/foreach_gcc.hpp"
#else
    #include "../impl/foreach_artima.hpp"
#endif

Changes to cxxomfort/cxxomfort/library/localfn.hpp.

91
92
93
94
95
96
97

98

99
100
101
102
103
104
105
#define FOR_EACH_(N, what, x, ...) CONCATENATE(FOR_EACH_, N)(what, x, __VA_ARGS__)
#define FOR_EACH(what, x, ...) FOR_EACH_(FOR_EACH_NARG(x, __VA_ARGS__), what, x, __VA_ARGS__)



#if defined CXXOMFORT_USING_LOCALFN
#if defined (CXXOMFORT_NOTICES)

    #pragma message CXXO_NOTICE("enabled local functor helpers" )

#endif



namespace cxxomfort {
namespace extras {








>

>







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#define FOR_EACH_(N, what, x, ...) CONCATENATE(FOR_EACH_, N)(what, x, __VA_ARGS__)
#define FOR_EACH(what, x, ...) FOR_EACH_(FOR_EACH_NARG(x, __VA_ARGS__), what, x, __VA_ARGS__)



#if defined CXXOMFORT_USING_LOCALFN
#if defined (CXXOMFORT_NOTICES)
    #if (CXXOMFORT_NOTICES > 1)
    #pragma message CXXO_NOTICE("enabled local functor helpers" )
    #endif
#endif



namespace cxxomfort {
namespace extras {

Changes to cxxomfort/cxxomfort/library/operatorit.hpp.

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
..
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
/**
 * @file library/operatorit.hpp
 * @brief Implementations and additions of ${operator}_it functoids similar to <functional>.
 * @addtogroup independent-features
 * 
 * Interfaces defined in this file:
 *

 * * plus_it, minus_it, multiplies_it, divides_it, modulus_it.
 * * leftshift_it, rightshift_it.
 * * comma_it.
 * * 
 *
 */

#include <cxxomfort/cxxomfort.hpp>
#include CXXO_INCLUDE_SYS(functional)

namespace cxxomfort {
namespace functional {





























#define CXXO_DEF_OPERATORIT(Name,Sym) \
template <typename It, typename Ot=It> \
struct Name : plus<int> {              \
    typedef It result_type;            \
    inline It& operator() (It& l, Ot const& r) const {   \
        return l Sym r;       \
................................................................................
 */

CXXO_DEF_OPERATORIT(plus_it,+=);
CXXO_DEF_OPERATORIT(minus_it,-=);
CXXO_DEF_OPERATORIT(multiplies_it,*=);
CXXO_DEF_OPERATORIT(divides_it,/=);
CXXO_DEF_OPERATORIT(modulus_it,%=);


/**
 * @}
 */

#undef CXXO_DEF_OPERATORIT

}
} // cxxomfort

#endif








>












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
>











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
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
 * @file library/operatorit.hpp
 * @brief Implementations and additions of ${operator}_it functoids similar to <functional>.
 * @addtogroup independent-features
 * 
 * Interfaces defined in this file:
 *
 * * preincrement, predecrement
 * * plus_it, minus_it, multiplies_it, divides_it, modulus_it.
 * * leftshift_it, rightshift_it.
 * * comma_it.
 * * 
 *
 */

#include <cxxomfort/cxxomfort.hpp>
#include CXXO_INCLUDE_SYS(functional)

namespace cxxomfort {
namespace functional {

template <typename T>
struct preincrement
:std::unary_function<T,T> {
    typedef T argument_type;
    typedef T result_type;
    T& operator() (T& t) const { ++t; return t; }
};

template<> struct preincrement<void> {
    template <typename T>
    T& operator() (T& t) const { ++t; return t; }
};

template <typename T>
struct predecrement
:std::unary_function<T,T> {
    typedef T argument_type;
    typedef T result_type;
    T& operator() (T& t) const { --t; return t; }
};

template<> struct predecrement<void> {
    template <typename T>
    T& operator() (T& t) { --t; return t; }

};


#define CXXO_DEF_OPERATORIT(Name,Sym) \
template <typename It, typename Ot=It> \
struct Name : plus<int> {              \
    typedef It result_type;            \
    inline It& operator() (It& l, Ot const& r) const {   \
        return l Sym r;       \
................................................................................
 */

CXXO_DEF_OPERATORIT(plus_it,+=);
CXXO_DEF_OPERATORIT(minus_it,-=);
CXXO_DEF_OPERATORIT(multiplies_it,*=);
CXXO_DEF_OPERATORIT(divides_it,/=);
CXXO_DEF_OPERATORIT(modulus_it,%=);
CXXO_DEF_OPERATORIT(leftshift_it,<<=);
CXXO_DEF_OPERATORIT(rightshift_it,>>=);
/**
 * @}
 */

#undef CXXO_DEF_OPERATORIT

}
} // cxxomfort

#endif

Changes to cxxomfort/cxxomfort/library/stringfn.hpp.

19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
 * * l_trim, r_trim
 * * trim
 * 
 */

#include <cstring>
#include <string>
#include <ostringstream>


namespace cxxomfort {
namespace string {

/**
 * Joins all contents from [ini,fin) into a string.
 * @ingroup independent-features
................................................................................


template <typename String, typename Pred>
void r_trim (String& s, Pred p) {
    using namespace std;
    // we find L = last position in s where p(L) is true
    // we use string's erase function (or just a copy constructor)
    typename String::reverse_iterator L = find_if_not(rbegin(s), rend(s), p);
    if (L == rend(s)) return;
    s= String(rend(s).base(), L.base());
}

template <typename String, typename Pred>
void trim (String& s, Pred p) {
    l_trim(s,p);
    r_trim(s,p);
}







|
>







 







|
|
|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
 * * l_trim, r_trim
 * * trim
 * 
 */

#include <cstring>
#include <string>
#include <sstream>
#include <cxxomfort/algorithm.hpp>

namespace cxxomfort {
namespace string {

/**
 * Joins all contents from [ini,fin) into a string.
 * @ingroup independent-features
................................................................................


template <typename String, typename Pred>
void r_trim (String& s, Pred p) {
    using namespace std;
    // we find L = last position in s where p(L) is true
    // we use string's erase function (or just a copy constructor)
    typename String::reverse_iterator L = find_if_not(s.rbegin(), s.rend(), p);
    if (L == s.rend()) return;
    s= String(s.rend().base(), L.base());
}

template <typename String, typename Pred>
void trim (String& s, Pred p) {
    l_trim(s,p);
    r_trim(s,p);
}

Changes to cxxomfort/cxxomfort/library/tuplefn.hpp.

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
...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
















134
135
136















137
138
139
140
141
//
// is_tuple -- for specializations of calls based on tuples in C++03
//

//! @addtogroup independent-features
template <typename T> struct is_tuple: traits::false_type {};

#if (CXXOMFORT_CXX_STD >= 2011) || defined(DOXYGEN_DOCS)


//! Inherits from @c true_type  if @p T  is a <code>std::tuple</code>.
template <typename... Args> struct is_tuple< std::tuple<Args...> >
: traits::true_type {};

#else // c++03

// assume implementation of tuple in tr1 and supports at least 10 elements
template <typename T1> struct is_tuple <std::tr1::tuple<T1> >
: traits::true_type {};
template <typename T1, typename T2> 
struct is_tuple <std::tr1::tuple<T1,T2> >
: traits::true_type {};
template <typename T1, typename T2, typename T3> 
struct is_tuple <std::tr1::tuple<T1,T2,T3> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4> 
struct is_tuple <std::tr1::tuple<T1,T2,T3,T4> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4, typename T5> 
struct is_tuple <std::tr1::tuple<T1,T2,T3,T4,T5> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> 
struct is_tuple <std::tr1::tuple<T1,T2,T3,T4,T5,T6> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> 
struct is_tuple <std::tr1::tuple<T1,T2,T3,T4,T5,T6,T7> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> 
struct is_tuple <std::tr1::tuple<T1,T2,T3,T4,T5,T6,T7,T8> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> 
struct is_tuple <std::tr1::tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >
: traits::true_type {};

// if compiler supports variadics, we can extend this
#if defined(__GNUC__) || CXXO_EMULATION_variadic==1
template <typename T0, typename T1, typename T2, typename T3, typename T4
        , typename T5, typename T6, typename T7, typename T8, typename T9, typename... TArgs> 
struct is_tuple <std::tr1::tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,TArgs...> >
: traits::true_type {};
#endif

#endif
................................................................................
 * tuple_shift: removes the first type from a tuple
 */

#if (0 && CXXOMFORT_CXX_STD >= 2011)

//! Shifts a tuple one type to the left, discarding the leftmost type.
//! @ingroup independent-utilities
template <typename A1, typename Args..., typename Indices...>
std::tuple<Args...> tuple_shift (std::tuple<A1,Args...> && _tuple) {
    using namespace std;
    return make_tuple( forward<Args...>(get<Indices...>(_tuple));
}
#else
// c++03 impl
















#endif


















}
} // cxxomfort::

#endif







|
>
>







|


|


|


|


|


|


|


|


|



|







 







|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





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
...
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
//
// is_tuple -- for specializations of calls based on tuples in C++03
//

//! @addtogroup independent-features
template <typename T> struct is_tuple: traits::false_type {};

#if (CXXOMFORT_CXX_STD >= 2011) || \
 (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_GCC && CXXOMFORT_CXX_EMULATION == 2011)

//! Inherits from @c true_type  if @p T  is a <code>std::tuple</code>.
template <typename... Args> struct is_tuple< std::tuple<Args...> >
: traits::true_type {};

#else // c++03

// assume implementation of tuple in tr1 and supports at least 10 elements
template <typename T1> struct is_tuple <std::tuple<T1> >
: traits::true_type {};
template <typename T1, typename T2> 
struct is_tuple <std::tuple<T1,T2> >
: traits::true_type {};
template <typename T1, typename T2, typename T3> 
struct is_tuple <std::tuple<T1,T2,T3> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4> 
struct is_tuple <std::tuple<T1,T2,T3,T4> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4, typename T5> 
struct is_tuple <std::tuple<T1,T2,T3,T4,T5> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> 
struct is_tuple <std::tuple<T1,T2,T3,T4,T5,T6> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> 
struct is_tuple <std::tuple<T1,T2,T3,T4,T5,T6,T7> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> 
struct is_tuple <std::tuple<T1,T2,T3,T4,T5,T6,T7,T8> >
: traits::true_type {};
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> 
struct is_tuple <std::tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >
: traits::true_type {};

// if compiler supports variadics, we can extend this
#if (CXXO_EMULATION_variadic==1)
template <typename T0, typename T1, typename T2, typename T3, typename T4
        , typename T5, typename T6, typename T7, typename T8, typename T9, typename... TArgs> 
struct is_tuple <std::tr1::tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,TArgs...> >
: traits::true_type {};
#endif

#endif
................................................................................
 * tuple_shift: removes the first type from a tuple
 */

#if (0 && CXXOMFORT_CXX_STD >= 2011)

//! Shifts a tuple one type to the left, discarding the leftmost type.
//! @ingroup independent-utilities
template <typename A1, typename... Args, typename... Indices>
std::tuple<Args...> tuple_shift (std::tuple<A1,Args...> && _tuple) {
    using namespace std;
    return make_tuple( forward<Args...>(get<Indices...>(_tuple));
}
#else
// c++03 impl
template <typename A0, typename A1>
std::tuple<A1> tuple_shift (std::tuple<A0,A1> const& t) {
    using std::get;
    return std::make_tuple( get<1>(t) );
}
template <typename A0, typename A1, typename A2>
std::tuple<A1,A2> tuple_shift (std::tuple<A0,A1,A2> const& t) {
    using std::get;
    return std::make_tuple( get<1>(t), get<2>(t) );
}
template <typename A0, typename A1, typename A2, typename A3>
std::tuple<A1,A2,A3> tuple_shift (std::tuple<A0,A1,A2,A3> const& t) {
    using std::get;
    return std::make_tuple( get<1>(t), get<2>(t), get<3>(t) );
}

#endif



//
// tuple_call (f, Tuple)
// calls f for each member of Tuple
//
#if (CXXOMFORT_CXX_STD >= 2011)
template <typename F, typename Tuple, typename std::enable_if< cxxomfort::tuple::is_tuple<Tuple>::value, F>::type>
F
#else
template <typename F, typename Tuple>
typename std::enable_if< cxxomfort::tuple::is_tuple<Tuple>::value, F>::type // F
#endif
tuple_call (F& f, Tuple& t) {
    return f;
}

}
} // cxxomfort::

#endif

Changes to cxxomfort/cxxomfort/limits.hpp.

13
14
15
16
17
18
19




20
21
22
23
24
25
26

#include "./config.hpp"
#include "./base.hpp"
#include "./type_traits.hpp"
#include "./util/meta.hpp"
#include <limits>
//#include <type_traits>





namespace cxxomfort {

namespace impl {
template <uintmax_t N, size_t base=2> struct log_ {
    static const size_t value = 1 + log_<N/base, base>::value;
};







>
>
>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

#include "./config.hpp"
#include "./base.hpp"
#include "./type_traits.hpp"
#include "./util/meta.hpp"
#include <limits>
//#include <type_traits>
#if (defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1))
#pragma message CXXO_NOTICE("enabled <limits> support.")
#endif


namespace cxxomfort {

namespace impl {
template <uintmax_t N, size_t base=2> struct log_ {
    static const size_t value = 1 + log_<N/base, base>::value;
};

Changes to cxxomfort/cxxomfort/memory.hpp.

14
15
16
17
18
19
20





21
22
23
24
25
26
27
 * Included:
 * - addressof.hpp
 * - unique_ptr.hpp
 */

#include "config.hpp"
#include "base/alignof.hpp"






/* alignas, aligned_storage */
#if ((CXXOMFORT_CXX_STD < 2011) && (CXXO_COMPILER_SUPPORT_alignment_tools==0))

//
// alignas
//







>
>
>
>
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 * Included:
 * - addressof.hpp
 * - unique_ptr.hpp
 */

#include "config.hpp"
#include "base/alignof.hpp"

#if (defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1))
#pragma message CXXO_NOTICE("enabled <memory> support.")
#endif


/* alignas, aligned_storage */
#if ((CXXOMFORT_CXX_STD < 2011) && (CXXO_COMPILER_SUPPORT_alignment_tools==0))

//
// alignas
//

Changes to cxxomfort/cxxomfort/tuple.hpp.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "base.hpp"
#include "utility.hpp" // index_sequence
#include <tuple> // d'uh
#include <array> // array <-> tuple conversions
#include <cxxomfort/library/tuplefn.hpp> // is_tuple

#if (defined(CXXOMFORT_NOTICES) && CXXOMFORT_NOTICES > 1)
    #pragma message CXXO_NOTICE("enabled tuple utilities")
#endif

/*
 * Given a tuple T<T1,T2,...>, obtain the function signature R(T1,T2,...)
 */









|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "base.hpp"
#include "utility.hpp" // index_sequence
#include <tuple> // d'uh
#include <array> // array <-> tuple conversions
#include <cxxomfort/library/tuplefn.hpp> // is_tuple

#if (defined(CXXOMFORT_NOTICES) && CXXOMFORT_NOTICES > 1)
    #pragma message CXXO_NOTICE("enabled <tuple> support")
#endif

/*
 * Given a tuple T<T1,T2,...>, obtain the function signature R(T1,T2,...)
 */


Changes to cxxomfort/cxxomfort/type_traits.hpp.

22
23
24
25
26
27
28




29
30
31
32
33
34
35
 * 
 */

#include "utility.hpp" // declval
#include <type_traits>
#include "util/type_traits.hpp"
#include "using.hpp" // bring TR1 in






/*
 * TR1 traits missing in c++03 in implementations 
 * is_literal_type, is_trivial, etc
 */








>
>
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 * 
 */

#include "utility.hpp" // declval
#include <type_traits>
#include "util/type_traits.hpp"
#include "using.hpp" // bring TR1 in

#if (defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1))
#pragma message CXXO_NOTICE("enabled <type_traits> support.")
#endif


/*
 * TR1 traits missing in c++03 in implementations 
 * is_literal_type, is_trivial, etc
 */

Changes to cxxomfort/cxxomfort/using.hpp.

43
44
45
46
47
48
49

50

51
52
53
54
55
56
57
    // #include-ing the headers first and availability of a header 
    // can not be checked at compile time.
    //
    // tl;dr: read the information on the repo wiki about TR1.

}
    #if defined(CXXOMFORT_NOTICES)

    #pragma message CXXO_NOTICE("importing TR1")

    #endif
#else // in C++11

//namespace std { namespace tr1 { using namespace std; } } //
#endif

#endif







>
|
>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    // #include-ing the headers first and availability of a header 
    // can not be checked at compile time.
    //
    // tl;dr: read the information on the repo wiki about TR1.

}
    #if defined(CXXOMFORT_NOTICES)
        #if (CXXOMFORT_NOTICES>1)
        #pragma message CXXO_NOTICE("importing TR1")
        #endif
    #endif
#else // in C++11

//namespace std { namespace tr1 { using namespace std; } } //
#endif

#endif

Changes to cxxomfort/cxxomfort/util/meta.hpp.

10
11
12
13
14
15
16
17
18
19


20
21
22
23
24
25
26
 * * identity
 * * disable_if
 * * selection
 * * meta_and, meta_or
 * 
 */

#include "../config.hpp"
#include "../base/static_assert.hpp"
#include "type_traits.hpp"



namespace cxxomfort {

struct none_tag ;

/**
 * @brief Given a type T, define member ::type as T







|
|

>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * * identity
 * * disable_if
 * * selection
 * * meta_and, meta_or
 * 
 */

#include <cxxomfort/config.hpp>
#include <cxxomfort/base/static_assert.hpp>
#include "type_traits.hpp"
#define CXXOMFORT_IMPLEMENTS_n2240 CXXO_LIBRARY()


namespace cxxomfort {

struct none_tag ;

/**
 * @brief Given a type T, define member ::type as T

Changes to cxxomfort/cxxomfort/util/traits_ct.hpp.

13
14
15
16
17
18
19


20

21


22




23
24
25
26
27
28
29
30
31
32
33
34
35
#include <ciso646>

#if (CXXOMFORT_CXX_STD >= 2011)
    // only do something if the specific compiler lacks std::common_type
#else // c++03
    #define CXXO_IMPLEMENT_COMMON_TYPE 1



    // MSVC 2010 already implements common_type, albeit broken; nothing we can do

    #if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_MSC && CXXOMFORT_COMPILER_VERSION==160)


        #undef CXXO_IMPLEMENT_COMMON_TYPE




    #endif

#endif // CXXOMFORT_CXX_STD


#if (CXXO_IMPLEMENT_COMMON_TYPE==1) // _IMPLEMENT_
/*
 * Unlike other utilities, common_type has to be implemented in namespace std 
 * because clients have to be able to specialize.
 * 
 * The only way around it would be to either hack MSVC 2010's <utility> 
 * or replacing the header whole via a cstd/cxx11/utility transparent header.
 * 







>
>
|
>
|
>
>
|
>
>
>
>





|







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
#include <ciso646>

#if (CXXOMFORT_CXX_STD >= 2011)
    // only do something if the specific compiler lacks std::common_type
#else // c++03
    #define CXXO_IMPLEMENT_COMMON_TYPE 1

    
    #if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_MSC && CXXOMFORT_COMPILER_VERSION==160)
        // MSVC 2010 already implements common_type, albeit broken; nothing we can do
        #undef CXXO_IMPLEMENT_COMMON_TYPE
    #elif (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC)
        // GCC ships common_type in "emulation" mode from 4.4 onwards
        #if (CXXOMFORT_COMPILER_VERSION >= 404 && CXXOMFORT_CXX_EMULATION==2011)
            #undef CXXO_IMPLEMENT_COMMON_TYPE
        #endif
    #else
        // unrecognized compiler
    
    #endif

#endif // CXXOMFORT_CXX_STD


#if defined(CXXO_IMPLEMENT_COMMON_TYPE) // _IMPLEMENT_
/*
 * Unlike other utilities, common_type has to be implemented in namespace std 
 * because clients have to be able to specialize.
 * 
 * The only way around it would be to either hack MSVC 2010's <utility> 
 * or replacing the header whole via a cstd/cxx11/utility transparent header.
 * 

Changes to cxxomfort/cxxomfort/utility.hpp.

20
21
22
23
24
25
26





27
28
29
30
31
32
33
..
40
41
42
43
44
45
46











47
48
49
50

51
52
53
54

55


56
57
58
59
60
61
62
 * 
 */

#include "base.hpp"   // move, forward
#include "util/meta.hpp"
#include "util/type_traits.hpp"
#include <type_traits>






namespace cxxomfort {
/**
 * @addtogroup utility 
 * @{
 */

................................................................................
namespace cxxomfort {
    //! @ingroup utility
    //! @ingroup cxx03-backports
    template <typename T> typename cxxomfort::traits::add_reference<T>::type declval();
}

#if (CXXOMFORT_CXX_STD < 2011)











namespace std { 
    //! @ingroup cxx03-backports
    using ::cxxomfort::declval;
} //std::

#endif
// MSVC 2010 does not ship with a declval
#if (CXXOMFORT_CXX_STD < 2011 && CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_MSC && CXXOMFORT_COMPILER_VERSION==150)
namespace std { using ::cxxomfort::declval; }

#endif




#include "impl/n3668_exchange.hpp"
#include "impl/14-integer_sequence.hpp"
#include "impl/17-as_const.hpp"

#endif







>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>

<


>
|
<
<
<
>

>
>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
..
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
 * 
 */

#include "base.hpp"   // move, forward
#include "util/meta.hpp"
#include "util/type_traits.hpp"
#include <type_traits>

#if (defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1))
#pragma message CXXO_NOTICE("enabled <utility> support.")
#endif


namespace cxxomfort {
/**
 * @addtogroup utility 
 * @{
 */

................................................................................
namespace cxxomfort {
    //! @ingroup utility
    //! @ingroup cxx03-backports
    template <typename T> typename cxxomfort::traits::add_reference<T>::type declval();
}

#if (CXXOMFORT_CXX_STD < 2011)
    #if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_MSC && CXXOMFORT_COMPILER_VERSION==150)
    // MSVC 2010 does not ship with a declval
        #define CXXO_ADD_declval 
    #elif (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC)
        #if (CXXOMFORT_CXX_EMULATION<2011)
            #define CXXO_ADD_declval
        #endif
    #else
        #define CXXO_ADD_declval
    #endif
    #if defined(CXXO_ADD_declval)
namespace std { 

    using ::cxxomfort::declval;
} //std::
        #undef CXXO_ADD_declval
    #endif




#endif
#define CXXOMFORT_IMPLEMENTS_n1978 CXXO_BACKPORT()
#define CXXOMFORT_IMPLEMENTS_n2343 CXXO_BACKPORT()


#include "impl/n3668_exchange.hpp"
#include "impl/14-integer_sequence.hpp"
#include "impl/17-as_const.hpp"

#endif

Changes to cxxomfort/tags/cxxomfort.cpp.tags.

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










# previous versions, and adds some convenience features.
#
# Fossil Repo: http://ryan.gulix.cl/fossil.cgi/cxxomfort
#
# @author Luis Machuca Bezzaza  <luis.machuca@gulix.cl>
# @version 1
# Tags for cxxomfort information
CXXOMFORT_VERSION|||
CXXOMFORT_DATE|||
CXXOMFORT_COMPILER_ID|||
CXXOMFORT_COMPILER_VERSION|||
# Tags for cxxomfort support
CXXOMFORT_CXX_STD|(integer)||
CXXOMFORT_CXX_EMULATION|(integer)||
# Tags for cxxomfort configuration
CXXOMFORT_NOTICES|||
# Tags for cxxomfort-specific utilities
CXXO_AUTO||(name , expression)|
CXXO_CONSTEXPR|||
CXXO_DECLTYPE|type?|(expression)|
CXXO_FOREACH||(key , sequence)|
CXXO_I12N_BEG||(Sequence_Type , Variable_Name)|
CXXO_I12N_END||(Sequence_Type , Variable_Name)|
CXXO_I12N_SEQ||(Sequence_Type , Variable_Name , { sequence...})|
CXXO_LOCALFN||(Signature)(arguments...){...}|
CXXO_LOCALFN_NAME_DEF||(Name,Signature)|
CXXO_NOEXCEPT|||
CXXO_PSEUDOVARIADIC_MEMBER||(prefix,func_name,suffix)|
CXXO_TYPEOF|type?|(expression)|
make_array_ref|array_ref<T>|(T[N])|
make_array_ref|array_ref<T>|(array / dynarray / valarray / vector)|
seq_|"sequence type"|<T>(...sequence of T)|
typeid_demangle|std::string|(typeid construct)|
type_name|std::string|<T>() [parametrized on T]|

















|
|
|
|

|
|

|


|







|







>
>
>
>
>
>
>
>
>
>
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
# previous versions, and adds some convenience features.
#
# Fossil Repo: http://ryan.gulix.cl/fossil.cgi/cxxomfort
#
# @author Luis Machuca Bezzaza  <luis.machuca@gulix.cl>
# @version 1
# Tags for cxxomfort information
CXXOMFORT_VERSION|unsigned int||
CXXOMFORT_DATE|unsigned long||
CXXOMFORT_COMPILER_ID|unsigned int||
CXXOMFORT_COMPILER_VERSION|unsigned int||
# Tags for cxxomfort support
CXXOMFORT_CXX_STD|int||
CXXOMFORT_CXX_EMULATION|int||
# Tags for cxxomfort configuration
CXXOMFORT_NOTICES|int||
# Tags for cxxomfort-specific utilities
CXXO_AUTO||(name , expression)|
CXXO_CONSTEXPR|expr||
CXXO_DECLTYPE|type?|(expression)|
CXXO_FOREACH||(key , sequence)|
CXXO_I12N_BEG||(Sequence_Type , Variable_Name)|
CXXO_I12N_END||(Sequence_Type , Variable_Name)|
CXXO_I12N_SEQ||(Sequence_Type , Variable_Name , { sequence...})|
CXXO_LOCALFN||(Signature)(arguments...){...}|
CXXO_LOCALFN_NAME_DEF||(Name,Signature)|
CXXO_NOEXCEPT|expr||
CXXO_PSEUDOVARIADIC_MEMBER||(prefix,func_name,suffix)|
CXXO_TYPEOF|type?|(expression)|
make_array_ref|array_ref<T>|(T[N])|
make_array_ref|array_ref<T>|(array / dynarray / valarray / vector)|
seq_|"sequence type"|<T>(...sequence of T)|
typeid_demangle|std::string|(typeid construct)|
type_name|std::string|<T>() [parametrized on T]|
#algorithm
find_last_if|Iterator|(Iterator ini, Iterator fin, Predicate f)|
transform_inplace|Iterator|(Iterator ini, Iterator fin, Function f)|
transform_n|Iterator|(Iterator ini, Integer n, DestIterator out, Function f)|
#functional
#string
#tuple
#utility
tuple_shift|tuple<A_2,...,A_(n)>|(tuple<A_1,A_2,...,A_(n)>)|
tuple_pop|tuple<A_1,A_2,...,A_(n-1)>|(tuple<A_1,A_2,...,A_(n-1),A_(n)>)|