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

Overview
Comment:Commit 2018-07-01 - Forward with library improvements, <numeric> and build logs.
  • cxxomfort: Corrected CXXOMFORT_NOTICES in various headers.
  • cxxomfort: Cleared most "typedef unused" warnings.
  • cxxomfort: Most if not all files converted to LF line endings.
  • cxxomfort: CXXOMFORT_DATE now uses full YYYYMMDD format.
  • cxxomfort: CXXOMFORT_NO_STD_USING.
  • cxxomfort: Added numeric.hpp and numerics to library.
  • cxxomfort: Header files also include javadoc code for generating future documentation.
  • library: algorithm: Added inplace_if.
  • library: numeric: Added static_gcd, static_lcm.
  • library: string: Added chr, wchr, utf8chr.
  • library: string: Added split_to.
  • impl: byte is moved to namespace cxxomfort::cstddef.
  • cstdint: Now c++11 emulation mode also relies on pstdint.h.
  • forward_list: Fixed the implementation of insert_after, emplace_after.
  • iterator: Removed warnings about unused typedefs in begin(), end().
  • memory: Updated make_unique as well as its STD requirements to go below C++14.
  • tuple: Removed a warning about aggregate brackets.
  • type_traits: enable_if, conditional moved to their own impl file.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:5862a10fe0f410be7e31fe59124cb1a9deaffccb
User & Date: luismachuca 2018-07-03 03:05:56
Context
2018-08-17
04:41
Commit 2018-08-17 - Corrections for MSVC 2010/2012 compat.
  • config: Fixed detection of MSVC 2010, 2012 features.
  • random: Fixed C++03 feature renames that are for GCC only.
  • string: Fixed missing strto(u)ll in MSVC 2010,2012 fixed.
  • string: Fixed to_string for MSVC 2012.
  • string: Fixed to_string, strtoull overloads for MSVC 2012.
  • type_traits: Added enable_if, conditional moved to their own file and fixed for C++03 support.
  • library: string: Fixed utf8chr function calls.
  • extras: array_ref: Fixed the fixed_vector constructor.
  • Upcoming Changes:
  • Changes to <functional>: functors.
  • Changes to <type_traits>: minimal TR1.
  • Additions to <cstddef>: user defined literals.
  • Additions to <functional>: not_fn.
  • Additions to cstd: <optional>.
  • Additions to cstd: <variant>.
  • Additions to <library/random>: distributor wrappers.
  • Additions to <library/string>: strsprintf.
check-in: 6fe18ebc user: luismachuca tags: trunk
2018-07-03
03:05
Commit 2018-07-01 - Forward with library improvements, <numeric> and build logs.
  • cxxomfort: Corrected CXXOMFORT_NOTICES in various headers.
  • cxxomfort: Cleared most "typedef unused" warnings.
  • cxxomfort: Most if not all files converted to LF line endings.
  • cxxomfort: CXXOMFORT_DATE now uses full YYYYMMDD format.
  • cxxomfort: CXXOMFORT_NO_STD_USING.
  • cxxomfort: Added numeric.hpp and numerics to library.
  • cxxomfort: Header files also include javadoc code for generating future documentation.
  • library: algorithm: Added inplace_if.
  • library: numeric: Added static_gcd, static_lcm.
  • library: string: Added chr, wchr, utf8chr.
  • library: string: Added split_to.
  • impl: byte is moved to namespace cxxomfort::cstddef.
  • cstdint: Now c++11 emulation mode also relies on pstdint.h.
  • forward_list: Fixed the implementation of insert_after, emplace_after.
  • iterator: Removed warnings about unused typedefs in begin(), end().
  • memory: Updated make_unique as well as its STD requirements to go below C++14.
  • tuple: Removed a warning about aggregate brackets.
  • type_traits: enable_if, conditional moved to their own impl file.
check-in: 5862a10f user: luismachuca tags: trunk
2017-12-24
20:55
Commit 2017-12-24 - Multuple [sic] improvements with a byte of Saturnalia.
  • cxxomfort: Added <algorithm>, <functional>, <iterator>, <utility> cstd forward headers.
  • cxxomfort: Added <cstdint> cstd forward header.
  • cstddef: Added byte from c++17.
  • library: Added the count_frequencies algorithms.
  • library: Fixed the 7-, 8-, and 9-argument c++03 signatures for to_string.
  • library: Library Utilities in <tuple.hpp> moved to the proper <library/tuplefn.hpp> header.
  • library: Added 6-, 7- and 8- tuple arguments overloads to tuple_pop, tuple_shift.
  • library: Added tuple_visit(function, tuple) (aka foreach for tuples).
  • tuple: Fixed tuple_apply(function,tuple) to correspond as a c++17 backport.
  • tuple: Added make_from_tuple from c++17 (it only works on actual tuples in c++03, c++11).
  • PENDING: library: Add tuple_if
check-in: 0c1dc33f user: luismachuca tags: trunk
Changes

Changes to cxxomfort/cxxomfort/VERSION.txt.

1
cxxomfort 0.54 2017-12-19
|
1
cxxomfort 0.70 2018-07-01

Changes to cxxomfort/cxxomfort/algorithm.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
..
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
...
176
177
178
179
180
181
182

183
184
185
186
187
188
189
...
200
201
202
203
204
205
206

207
208
209
210
211
212
213
...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278




















279
#ifndef CXXOMFORT_ALGORITHM_HPP
#define CXXOMFORT_ALGORITHM_HPP
/**
 * @file algorithm.hpp
 * @brief Implementations and additions tied to <algorithm>.
 * 
 * Interfaces defined in this file:
 * 
 * * @c [all,any,none]_of
 * * @c copy_if, @c copy_n, @c partition_copy
 * * @c equal (C++14)
 * * @c find_if_not
 * * @c iota
 * * @c is_permutation, @c next_permutation, @c prev_permutation
 * * @c is_sorted
 * * @c minmax, @c minmax_element
 * * @c count_while (STDC++ Forums proposal)
 * 
 * Pending:
 * 
 * * @c shuffle
 *
 * Documentation: @link Algorithms @endlink .
 * 
 */

#include "base.hpp"
#include "util/meta.hpp" // conditional
#include CXXO_INCLUDE_SYS(algorithm)


namespace cxxomfort {





namespace algorithm {

/**

 * @addtogroup algorithm
 * @{
 */


//! copy elements conditionally to @a dest if they fulfill @a f .
//! @return the advanced @a dest iterator.



template <typename InpI, typename OutI, typename Predicate>
inline OutI copy_if (InpI ini, InpI fin, OutI dest, Predicate f) {
    if (ini != fin) {
        for (; ini != fin; ++ini) {
            if (f(*ini)) { *dest++= *ini; }
        } // for
        
................................................................................
        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;
}

//! Fills @p n elements with an incrementing sequence starting from @p i0 .
template <typename FwIt, typename Integer, typename T>
FwIt iota_n (FwIt ini, Integer n, T i0) {
    while (n-->0) { *ini= i0; ++ini; ++i0; }
    return ini;
}


//! Check if a sequence is sorted according to comparison predicate @p less .



template <typename Iterator, typename Compare>
inline bool is_sorted (Iterator ini, Iterator fin, Compare less) {
    if (ini == fin) return true;
    Iterator prev= ini++;
    for (; ini != fin; ++ini, ++prev) {
        if (!less(*prev,*ini)) return false;
    }
    return true;
}

//! Check if a sequence is sorted according to <code>operator<</code>.
//! @return @c bool .
template <typename Iterator>
inline bool is_sorted (Iterator ini, Iterator fin) {
    std::less<typename std::iterator_traits<Iterator>::value_type> less;
    return is_sorted(ini,fin,less);
}


//
// minmax, minmax_element
//

//! return a @c std::pair (min,max) from two arguments and a comparator @a Less .
template <typename T, typename Comparator>
std::pair<T const&, T const&> minmax (T const& a, T const& b, Comparator Less) {
    return Less(b,a) ? 
    std::make_pair(b, a) : std::make_pair(a, b)
    ;
}

//! @overloads minmax
template <typename T>
std::pair<T const&, T const&> minmax (T const& a, T const& b)  {
    return (b < a) ? 
    std::pair<T const&,T const&>(b, a) : std::pair<T const&,T const&>(a, b)
    ;
}

................................................................................
            }
        }
    }
    return result;

}


template <typename FIterator>
std::pair<FIterator,FIterator> 
minmax_element (FIterator ini, FIterator fin) {
    std::less <typename std::iterator_traits<FIterator>::value_type> less;
    return minmax_element(ini, fin, less);
}

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

} // detail_algorithm


/*
 * Shuffles a sequence according to a generator call g().
 * Requires support from <random>.

 */
template< class RAIterator, class URNG >
void shuffle( RAIterator ini, RAIterator fin, URNG& g ) {
    typedef typename std::iterator_traits<RAIterator>::difference_type diff_t;
    diff_t n = fin - ini; // guaranteed for RAIterator
    for (diff_t i = n-1; i > 0; --i) {
        using std::swap;
................................................................................

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

    using ::cxxomfort::algorithm::find_if_not;
    using ::cxxomfort::algorithm::iota;

    using ::cxxomfort::algorithm::is_sorted;
    using ::cxxomfort::algorithm::minmax;
    using ::cxxomfort::algorithm::minmax_element;
    using ::cxxomfort::algorithm::shuffle;
    
    using ::cxxomfort::algorithm::for_each_n;
    
}
#endif // std using

#endif // using emulation





















#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
30
31
32
33
34
35
36
37
38
39
40
..
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
...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
...
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
#ifndef CXXOMFORT_ALGORITHM_HPP
#define CXXOMFORT_ALGORITHM_HPP
/**
 * @file algorithm.hpp
 * @brief Header file for the <algorithm>-related backports.
 * @ingroup std:algorithm


















 */

#include "base.hpp"
#include "util/meta.hpp" // conditional
#include CXXO_INCLUDE_SYS(algorithm)


namespace cxxomfort {
/**
 * @namespace
 * @brief Namespace for the <algorithm>-related backports.
 * @sa @ref cxxo:sup:algorithm
 */
namespace algorithm {

/**
 * @ingroup cxx11-backports
 * @ingroup std:algorithm
 * @{
 */

/**
 * @brief Copy elements conditionally to @a dest if they fulfill @a f .
 * @return the advanced @a dest iterator.
 * @anchor copy_if
 * @ref cxx11-backports
 */
template <typename InpI, typename OutI, typename Predicate>
inline OutI copy_if (InpI ini, InpI fin, OutI dest, Predicate f) {
    if (ini != fin) {
        for (; ini != fin; ++ini) {
            if (f(*ini)) { *dest++= *ini; }
        } // for
        
................................................................................
        if (!f(*ini)) {
            return ini;
        }
    }
    return fin; // < all the elements fulfill f
}

/**














 * @brief Determines if a sequence is sorted according to a given criteria.
 * @param less Criteria for sorting, a binary function f(x,y) that returns @c true if <code>x<y</code>.
 * @return A bool response about if the sequence is sorted.
 */
template <typename Iterator, typename Compare>
inline bool is_sorted (Iterator ini, Iterator fin, Compare less) {
    if (ini == fin) return true;
    Iterator prev= ini++;
    for (; ini != fin; ++ini, ++prev) {
        if (!less(*prev,*ini)) return false;
    }
    return true;
}

//! @overload is_sorted

template <typename Iterator>
inline bool is_sorted (Iterator ini, Iterator fin) {
    std::less<typename std::iterator_traits<Iterator>::value_type> less;
    return is_sorted(ini,fin,less);
}


//
// minmax, minmax_element
//

//! return a <code>pair(min,max)</code> from two arguments and a comparator @a Less .
template <typename T, typename Comparator>
std::pair<T const&, T const&> minmax (T const& a, T const& b, Comparator Less) {
    return Less(b,a) ? 
    std::make_pair(b, a) : std::make_pair(a, b)
    ;
}

//! @overload minmax
template <typename T>
std::pair<T const&, T const&> minmax (T const& a, T const& b)  {
    return (b < a) ? 
    std::pair<T const&,T const&>(b, a) : std::pair<T const&,T const&>(a, b)
    ;
}

................................................................................
            }
        }
    }
    return result;

}

//! @overload minmax_element
template <typename FIterator>
std::pair<FIterator,FIterator> 
minmax_element (FIterator ini, FIterator fin) {
    std::less <typename std::iterator_traits<FIterator>::value_type> less;
    return minmax_element(ini, fin, less);
}

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

} // detail_algorithm


/*
 * Shuffles a sequence according to a generator call g().
 * Requires support from <random>.
 * @anchor shuffle
 */
template< class RAIterator, class URNG >
void shuffle( RAIterator ini, RAIterator fin, URNG& g ) {
    typedef typename std::iterator_traits<RAIterator>::difference_type diff_t;
    diff_t n = fin - ini; // guaranteed for RAIterator
    for (diff_t i = n-1; i > 0; --i) {
        using std::swap;
................................................................................

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

    using ::cxxomfort::algorithm::find_if_not;
    //using ::cxxomfort::algorithm::iota;

    using ::cxxomfort::algorithm::is_sorted;
    using ::cxxomfort::algorithm::minmax;
    using ::cxxomfort::algorithm::minmax_element;
    using ::cxxomfort::algorithm::shuffle;
    
    using ::cxxomfort::algorithm::for_each_n;
    
}
#endif // std using

#endif // using emulation

/**
 * @page algorithm
 * @brief Implementations and additions tied to <algorithm>.
 * 
 * Interfaces defined in this file:
 * 
 * * @c [all,any,none]_of
 * * @c copy_if(), @c copy_n(), @c partition_copy()
 * * @c @ref equal() (C++14)
 * * @c @ref find_if_not()
 * * @c is_permutation(), @c next_permutation(), @c prev_permutation()
 * * @c @ref is_sorted()
 * * @c @ref minmax() , @c minmax_element()
 * 
 * Pending:
 * 
 * * @c shuffle
 *
 */

#endif

Changes to cxxomfort/cxxomfort/algorithms.hpp.

Changes to cxxomfort/cxxomfort/base.hpp.

1
2
3
4
5
6
7
8
9
10


11
12
13
14
15
16
17
#ifndef CXXOMFORT_BASE_HPP
#define CXXOMFORT_BASE_HPP
/**
 * @file cxxomfort/base.hpp
 * @brief Minimal cxxomfort setup.
 * 
 * For more complete cxxomfort setup (includes more headers, adds new names 
 * and functions) include "cxxomfort.hpp".
 */



#include "config.hpp"

// -- Cxxomfort basic features, always enabled by default --
#include "./base/alignof.hpp" // alignof impl
#include "./base/nullptr.hpp" // nullptr
#include "./base/static_assert.hpp" // static_assert
#include "./base/cstdint.hpp" // c++11 integer types ([u]intNN_t)



|






>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef CXXOMFORT_BASE_HPP
#define CXXOMFORT_BASE_HPP
/**
 * @file
 * @brief Minimal cxxomfort setup.
 * 
 * For more complete cxxomfort setup (includes more headers, adds new names 
 * and functions) include "cxxomfort.hpp".
 */

//#include <cstddef>
//#include <ciso646>
#include "config.hpp"

// -- Cxxomfort basic features, always enabled by default --
#include "./base/alignof.hpp" // alignof impl
#include "./base/nullptr.hpp" // nullptr
#include "./base/static_assert.hpp" // static_assert
#include "./base/cstdint.hpp" // c++11 integer types ([u]intNN_t)

Changes to cxxomfort/cxxomfort/base/alignof.hpp.

1
2
3
4
5
6
7
8
9
10
11
#ifndef CXXOMFORT_ALIGNOF_HPP
#define CXXOMFORT_ALIGNOF_HPP
/**
 * @file base/alignof.hpp
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces defined in this file:
 * 
 * * alignof (macro) (only for c++03 where __alignof is available)
 * 
 * Backported for C++03



|







1
2
3
4
5
6
7
8
9
10
11
#ifndef CXXOMFORT_ALIGNOF_HPP
#define CXXOMFORT_ALIGNOF_HPP
/**
 * @file
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces defined in this file:
 * 
 * * alignof (macro) (only for c++03 where __alignof is available)
 * 
 * Backported for C++03

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

1
2




3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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 (CXXOMFORT_CXX_STD>=2011 || CXXOMFORT_CXX_EMULATION >= 2011)
    #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


>
>
>
>








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef CXXOMFORT_BASE_CSTDINT_HPP
#define CXXOMFORT_BASE_CSTDINT_HPP
/**
 * @file
 */

/*
 * 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 (CXXOMFORT_CXX_STD>=2011)
    #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

Changes to cxxomfort/cxxomfort/base/explicit_cast.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
#ifndef CXXOMFORT_UTIL_EXPLICIT_CAST_HPP
#define CXXOMFORT_UTIL_EXPLICIT_CAST_HPP
/**
 * @file cxxomfort/util/explicit_cast.hpp
 * @brief Explicit cast, and @c explicit_cast conversion operator for C++03
 * 
 * Interfaces defined in this header:
 * 
 * * @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) {}
    //explicit_cast ( CXXO_RV_REF(T) p) : value(std::move(p)) {}
    operator T () const CXXO_NOEXCEPT { return value; }
};









#else
//template <typename T, typename U>
//T explicit_cast (U&& u) { return static_cast<T>(u); }
#define explicit_cast static_cast


/*
template <typename T>
struct explicit_cast {
    T value;
    template <typename U>
    explicit_cast (U u): value(static_cast<T>(u)) {}
................................................................................
    explicit_cast (T const& t) : value(t) {}
    explicit_cast (T&& t) : value(std::move(t)) {}
    operator T () const { return value; }
};
*/
#endif

}
} // cxxomfort::





#if defined(DOXYGEN_DOC)
/**
 * @def CXXO_EXPLICIT_OPERATOR(T)
 * @brief Implements a member conversion operator that provides explicit conversion
 * @ingroup base-features
 * 
 * This macro creates a conversion operator that provides an explicit conversion 
 * to a type of argument type @p T .
 * 
 * In C++11, this is defined to be a native <code>explicit operator T</code>; 
 * in C++03, this is defined to be an accessory conversion that the caller 
 * enabled by using <code>explicit_cast<T>(...)</code>.
 * 
 */
#define CXXO_EXPLICIT_OPERATOR(T)  implementation_defined
/**
 * @brief Explicitly cast an object of type F to a type T
 * @ingroup base-features
 * 
 * This pseudo-keyword performs an @c explicit -using cast on an object @em f 
 * to a target type @em T .
 * 
 * In C++11, this is defined to be a native <code>static_cast</code>; 
 * in C++03, this uses a fake cast.
 */
template <typename T, typename F>
T explicit_cast (F f) { return implementation_defined_cast<T>(f); }
#endif

// sync this #if with the top feature one
#if (CXXOMFORT_CXX_STD < 2011 && CXXO_COMPILER_SUPPORT_explicit_operator==0)
    #define CXXO_EXPLICIT_OPERATOR(T) operator ::cxxomfort::detail_explicit_cast::explicit_cast<T> 

using ::cxxomfort::detail_explicit_cast::explicit_cast;
#else
    #define CXXO_EXPLICIT_OPERATOR(T) explicit operator T 

#endif


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



#ifndef CXXOMFORT_BASE_EXPLICIT_CAST_HPP
#define CXXOMFORT_BASE_EXPLICIT_CAST_HPP
/**
 * @file
 * @brief Explicit cast, and @c explicit_cast conversion operator for C++03
 * 
 * Interfaces defined in this header:
 * 
 * * @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()


#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
namespace cxxomfort {
namespace detail_explicit_cast {







    template <typename T>
    struct explicit_cast {
        T value;
        explicit_cast (T const& t) CXXO_NOEXCEPT : value(t) {}
        //explicit_cast ( CXXO_RV_REF(T) p) : value(std::move(p)) {}
        operator T () const CXXO_NOEXCEPT { return value; }
    };

    #define CXXO_EXPLICIT_OPERATOR(T) operator ::cxxomfort::detail_explicit_cast::explicit_cast<T> 


}
} // cxxomfort::

using ::cxxomfort::detail_explicit_cast::explicit_cast;

#else
//template <typename T, typename U>
//T explicit_cast (U&& u) { return static_cast<T>(u); }
    #define explicit_cast static_cast
    #define CXXO_EXPLICIT_OPERATOR(T) explicit operator T 

/*
template <typename T>
struct explicit_cast {
    T value;
    template <typename U>
    explicit_cast (U u): value(static_cast<T>(u)) {}
................................................................................
    explicit_cast (T const& t) : value(t) {}
    explicit_cast (T&& t) : value(std::move(t)) {}
    operator T () const { return value; }
};
*/
#endif


// sync this #if with the top feature one
#if (CXXOMFORT_CXX_STD < 2011 /* && CXXO_COMPILER_SUPPORT_explicit_operator==0 */)
#else

#endif

#if defined(DOXYGEN_DOC)
/**
 * @def CXXO_EXPLICIT_OPERATOR(T)
 * @brief Implements a member conversion operator that provides explicit conversion
 * @ingroup independent-features
 * 
 * This macro creates a conversion operator that provides an explicit conversion 
 * to a type of argument type @p T .
 * 
 * In C++11, this is defined to be a native <code>explicit operator T</code>; 
 * in C++03, this is defined to be an accessory conversion that the caller 
 * enabled by using <code>explicit_cast<T>(...)</code>.
 * 
 */
#define CXXO_EXPLICIT_OPERATOR(T)  implementation_defined
/**
 * @brief Explicitly cast an object of type F to a type T
 * @ingroup independent-features
 * 
 * This pseudo-keyword performs an @c explicit -using cast on an object @em f 
 * to a target type @em T .
 * 
 * In C++11, this is defined to be a native <code>static_cast</code>; 
 * in C++03, this uses an intermediate cast.
 */
template <typename T, typename F>
T explicit_cast (F f) { return implementation_defined_cast<T>(f); }
#endif









#endif



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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
..
24
25
26
27
28
29
30













31





32
33
34
35
36
37
38
..
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
...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
...
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
#ifndef CXXOMFORT_ITERATOR_HPP
#define CXXOMFORT_ITERATOR_HPP
/**
 * @file cxxomfort/iterator.hpp
 * @brief Implements some C++11 functions in C++03 from the "iterator" header.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 * @ingroup base-features
 *
 * Interfaces defined in this header:
 *
 * * begin, end (also for namespace std)
 * * next, prev (also for namespace std)
 * * cbegin (also for namespace std)
 * * cend (also for namespace std)
................................................................................
#endif

//#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC)
//#pragma GCC diagnostic warning "-Wunused-local-typedefs
//#endif

namespace cxxomfort {













namespace iterator {






//
// Detect the presence of begin, end, size, front and back member functions
//
template <typename T>
struct iterator_accessors_helper {

................................................................................
 * "typedef defined but not used" warnings that can turn 
 * into errors in strict builds.
 */
#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC \
    && CXXOMFORT_COMPILER_VERSION >= 406)
#pragma GCC system_header
#endif






//! Returns the "begin" iterator for a container-like object.
//! @ingroup iterator
//! @ref cxx03-backports
template <typename C>
typename C::iterator inline
begin (C & c) {
    typedef typename C::iterator iterator;
    typedef typename C::value_type value_type;
    return c.begin();
}

//! @overloads cxxomfort::begin
template <typename C> inline
typename C::const_iterator
begin (C const& c) {
    typedef typename C::const_iterator const_iterator;
    //typedef typename C::size_type size_type;
    typedef typename C::value_type value_type;
    return c.begin();
}

//! C++14 "overload" of begin to always return const-iterator
//! @ingroup iterator
//! @ref cxx03-backports
//! @ref cxx11-backports
template <typename C> inline
typename C::const_iterator
cbegin (C const& c)  {
    typedef typename C::const_iterator const_iterator;
    //typedef typename C::size_type size_type;
    typedef typename C::value_type value_type;
    return cxxomfort::iterator::begin(c);
}

//! @overloads cxxomfort::begin 
template <typename T, std::size_t N> inline
T* begin (T(&arr)[N]) { return arr; }

//! @overloads cbegin
template <typename T, std::size_t N> inline
T const* cbegin (T const(&arr)[N]) { return arr; }

//! Returns the "end" iterator for a container-like object.
//! @ingroup iterator
//! @ref cxx03-backports
template <typename C> inline
typename C::iterator
end (C & c) {
    typedef typename C::iterator iterator;
    typedef typename C::difference_type difference_type;
    typedef typename C::value_type value_type;
    return c.end();
}

//! @overloads cxxomfort::end 
template <typename C> inline
typename C::const_iterator
end (C const& c) {
    typedef typename C::const_iterator iterator;
    //typedef typename C::size_type size_type;
    typedef typename C::value_type value_type;
    return c.end();
}

//! C++14 "overload" to always return const-iterator
//! @ingroup iterator
//! @ref cxx03-backports
//! @ref cxx11-backports
template <typename C> inline
typename C::const_iterator
cend (C const& c)  {
    typedef typename C::const_iterator const_iterator;
    //typedef typename C::size_type size_type;
    typedef typename C::value_type value_type;
    return cxxomfort::iterator::end(c);
}

//! @overloads end
template <typename T, size_t N> inline
T* end (T(&arr)[N]) { return arr+N; }

//! @overloads cend
template <typename T, size_t N> inline
T const* cend (T const(&arr)[N]) { return arr+N; }

// From C++14 / 2y
template <typename C>
typename C::reverse_iterator inline
rbegin (C & c) {
    typedef typename C::reverse_iterator iterator;
    typedef typename C::difference_type difference_type;
    typedef typename C::value_type value_type;
    return c.rbegin();
}


template <typename C>
typename C::reverse_iterator inline
rend (C & c) {
    typedef typename C::reverse_iterator iterator;
    typedef typename C::difference_type difference_type;
    typedef typename C::value_type value_type;
    return c.rend();
}

//! @overloads cxxomfort::rbegin 
template <typename T, std::size_t N> inline
std::reverse_iterator<T*> rbegin (T(&arr)[N]) { return std::reverse_iterator<T*>(arr+N); }

//! @overloads cxxomfort::rend 
template <typename T, std::size_t N> inline
std::reverse_iterator<T*> rend (T(&arr)[N]) { return std::reverse_iterator<T*>(arr); }


/**
 * @brief Moves an iterator forwards an amount of steps, returning the result.
 * @ingroup iterator
................................................................................
) {
    std::advance(i, n);
    return i;
}

/**
 * @brief Moves an iterator backwards an amount of steps, returning the result.
 * @ingroup iterator
 * @ref cxx03-backports
 *
 * This is reflected as @c std::prev .
 */
template <typename FIterator> inline
FIterator prev (FIterator i
, typename std::iterator_traits<FIterator>::difference_type n = 1
) {
................................................................................

} // detail_size

template <typename C> inline
typename C::difference_type
size (C & c) {
    typedef typename C::iterator iterator;

    typedef typename C::difference_type difference_type;

    typedef typename C::value_type value_type;

    const detail_size::call_size_has< C, iterator_accessors_helper<C>::has_size > s={};
    return s(c);
}

// overload for native arrays
template <typename T, size_t N> inline
size_t size (T(&arr)[N]) {

    return N;
}

#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC \
    && CXXOMFORT_COMPILER_VERSION >= 408)
#pragma GCC diagnostic pop
#endif




} // ~::cxxomfort::iterator
} // ~::cxxomfort



#if defined CXXOMFORT_USING_ITERATOR
    #if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 2)
    #pragma message CXXO_NOTICE("enabled iterator functions support.")
    #endif

#include CXXO_INCLUDE_SYS(iterator)



|
|
|
<







 







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







 







|
>
>
>
>
>
|
<
|



|
|



|



|
<
|




<
<
|



|
<
|



|



|




<
|



|
<
|



|



|
<
|




<
<
|



<
<
<



|



|



|



|
<
|



>



|
<
|



|



|







 







|
|







 







>
|
>
|
>







>








>
>
>
|
|
<
<







1
2
3
4
5
6

7
8
9
10
11
12
13
..
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
..
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
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
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
#ifndef CXXOMFORT_ITERATOR_HPP
#define CXXOMFORT_ITERATOR_HPP
/**
 * @file
 * @brief Implements some C++11 functions in C++03 from the "iterator" header.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>

 *
 * Interfaces defined in this header:
 *
 * * begin, end (also for namespace std)
 * * next, prev (also for namespace std)
 * * cbegin (also for namespace std)
 * * cend (also for namespace std)
................................................................................
#endif

//#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC)
//#pragma GCC diagnostic warning "-Wunused-local-typedefs
//#endif

namespace cxxomfort {
/**
 * @page iterator
 * @namespace iterator
 * 
 * Utilities and functions backported for the <code><iterator></code> header.
 * 
 * Facilities backported here include:
 * 
 * * @ref begin , @ref end
 * * @ref cbegin , @ref cend
 * * non-member @ref size 
 * 
 */
namespace iterator {

template <typename T>
struct check_type {
    enum { s = sizeof(T) };
};

//
// Detect the presence of begin, end, size, front and back member functions
//
template <typename T>
struct iterator_accessors_helper {

................................................................................
 * "typedef defined but not used" warnings that can turn 
 * into errors in strict builds.
 */
#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC \
    && CXXOMFORT_COMPILER_VERSION >= 406)
#pragma GCC system_header
#endif

/**
 * @ingroup iterator
 * @{
 */

//! Returns the "begin" iterator for a container-like object.

//! @ref cxx11-backports
template <typename C>
typename C::iterator inline
begin (C & c) {
    static_assert(sizeof(typename C::iterator), "");
    static_assert(sizeof(typename C::value_type), "");
    return c.begin();
}

//! @overload cxxomfort::begin
template <typename C> inline
typename C::const_iterator
begin (C const& c) {
    static_assert(sizeof(typename C::const_iterator), "");

    static_assert(sizeof(typename C::value_type), "");
    return c.begin();
}

//! C++14 "overload" of begin to always return const-iterator


//! @ref cxx14-backports
template <typename C> inline
typename C::const_iterator
cbegin (C const& c)  {
    static_assert(sizeof(typename C::const_iterator), "");

    static_assert(sizeof(typename C::value_type), "");
    return cxxomfort::iterator::begin(c);
}

//! @overload cxxomfort::begin 
template <typename T, std::size_t N> inline
T* begin (T(&arr)[N]) { return arr; }

//! @overload cbegin
template <typename T, std::size_t N> inline
T const* cbegin (T const(&arr)[N]) { return arr; }

//! Returns the "end" iterator for a container-like object.

//! @ref cxx11-backports
template <typename C> inline
typename C::iterator
end (C & c) {
    static_assert(sizeof(typename C::iterator), "");

    static_assert(sizeof(typename C::value_type), "");
    return c.end();
}

//! @overload cxxomfort::end 
template <typename C> inline
typename C::const_iterator
end (C const& c) {
    static_assert(sizeof(typename C::const_iterator), "");

    static_assert(sizeof(typename C::value_type), "");
    return c.end();
}

//! C++14 "overload" to always return const-iterator


//! @ref cxx14-backports
template <typename C> inline
typename C::const_iterator
cend (C const& c)  {



    return cxxomfort::iterator::end(c);
}

//! @overload end
template <typename T, size_t N> inline
T* end (T(&arr)[N]) { return arr+N; }

//! @overload cend
template <typename T, size_t N> inline
T const* cend (T const(&arr)[N]) { return arr+N; }

//! @ref cxx14-backports
template <typename C>
typename C::reverse_iterator inline
rbegin (C & c) {
    static_assert(sizeof(typename C::reverse_iterator), "");

    static_assert(sizeof(typename C::value_type), "");
    return c.rbegin();
}

//! @ref cxx14-backports
template <typename C>
typename C::reverse_iterator inline
rend (C & c) {
    static_assert(sizeof(typename C::reverse_iterator), "");

    static_assert(sizeof(typename C::value_type), "");
    return c.rend();
}

//! @overload cxxomfort::rbegin 
template <typename T, std::size_t N> inline
std::reverse_iterator<T*> rbegin (T(&arr)[N]) { return std::reverse_iterator<T*>(arr+N); }

//! @overload cxxomfort::rend 
template <typename T, std::size_t N> inline
std::reverse_iterator<T*> rend (T(&arr)[N]) { return std::reverse_iterator<T*>(arr); }


/**
 * @brief Moves an iterator forwards an amount of steps, returning the result.
 * @ingroup iterator
................................................................................
) {
    std::advance(i, n);
    return i;
}

/**
 * @brief Moves an iterator backwards an amount of steps, returning the result.
 * @ingroup cxx11-backports
 * @ref iterator
 *
 * This is reflected as @c std::prev .
 */
template <typename FIterator> inline
FIterator prev (FIterator i
, typename std::iterator_traits<FIterator>::difference_type n = 1
) {
................................................................................

} // detail_size

template <typename C> inline
typename C::difference_type
size (C & c) {
    typedef typename C::iterator iterator;
    (void)iterator();
    typedef typename C::difference_type difference_type;
    (void)difference_type();
    typedef typename C::value_type value_type;
    (void)value_type();
    const detail_size::call_size_has< C, iterator_accessors_helper<C>::has_size > s={};
    return s(c);
}

// overload for native arrays
template <typename T, size_t N> inline
size_t size (T(&arr)[N]) {
    (void)arr;
    return N;
}

#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC \
    && CXXOMFORT_COMPILER_VERSION >= 408)
#pragma GCC diagnostic pop
#endif

/**
 * @}
 */
} // ~::cxxomfort::iterator
} // ~::cxxomfort



#if defined CXXOMFORT_USING_ITERATOR
    #if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 2)
    #pragma message CXXO_NOTICE("enabled iterator functions support.")
    #endif

#include CXXO_INCLUDE_SYS(iterator)

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

1
2
3
4
5
6
7


8
9
10
11
12
13
14
15
16
17
..
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#ifndef CXXOMFORT_UTIL_MOVE_03_HPP
#define CXXOMFORT_UTIL_MOVE_03_HPP

// Move emulation, deboostified from Boost
// (Dunno what's the point, Boost.Move is pretty self-standing)

#include "../config.hpp"


#include "../util/type_traits.hpp"
#include "../util/meta.hpp"
#include "../impl/11-addressof.hpp"
#if (CXXOMFORT_CXX_STD >= 2011)
    #error Library error - this file should only be invoked with c++03
#endif


//Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
#ifdef __GNUC__
................................................................................
};

struct empty {};
}

template <class T>
class rv
: public ::cxxomfort::conditional
    < (traits::is_class<T>::value || traits::is_union<T>::value)
    , T
    , move_detail::empty
>::type {
    rv();
    ~rv();
    rv(rv const&);







>
>
|
|
<







 







|







1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
..
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#ifndef CXXOMFORT_UTIL_MOVE_03_HPP
#define CXXOMFORT_UTIL_MOVE_03_HPP

// Move emulation, deboostified from Boost
// (Dunno what's the point, Boost.Move is pretty self-standing)

#include "../config.hpp"
#include "../impl/11-conditional.hpp"
#include "../impl/11-addressof.hpp"
#include "../util/type_traits.hpp"
#include "../util/meta.hpp"

#if (CXXOMFORT_CXX_STD >= 2011)
    #error Library error - this file should only be invoked with c++03
#endif


//Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
#ifdef __GNUC__
................................................................................
};

struct empty {};
}

template <class T>
class rv
: public std::conditional
    < (traits::is_class<T>::value || traits::is_union<T>::value)
    , T
    , move_detail::empty
>::type {
    rv();
    ~rv();
    rv(rv const&);

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

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

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef CXXOMFORT_UTIL_MOVE_HPP
#define CXXOMFORT_UTIL_MOVE_HPP

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


/*
 * Usage example




|







1
2
3
4
5
6
7
8
9
10
11
12
#ifndef CXXOMFORT_UTIL_MOVE_HPP
#define CXXOMFORT_UTIL_MOVE_HPP

/**
 * @file
 * @brief Implements movable objects functionality in C++03 .
 *
 */


/*
 * Usage example

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

1
2
3
4
5
6
7
8
9
10
11
..
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
..
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#ifndef CXXOMFORT_NULLPTR_HPP
#define CXXOMFORT_NULLPTR_HPP
/**
 * @file cxxomfort/nullptr.hpp
 * @brief Implements @c nullptr as a comfort utility for C++03.
 * @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)
................................................................................
namespace std {

// This is pretty much borrowed from the Standards recommendation verbatim.

/**
 * @class nullptr_t
 * @brief Null pointer literal type.
 * @ingroup base-features
 * @ref cxx03-backports
 * 
 * @attention No variables of this type can be created.
 *
 * @c nullptr_t is defined in the C++0x Standard as the type of the
 * keyword "@c nullptr ", via decltype. In C++98 / C++03,
 * an emulation is provided and recommended by the Standard.
 *
................................................................................
};



} //~namespace std

/**
 * @var nullptr
 * @brief Null pointer literal (backport)
 * @anchor nullptr
 * @addtogroup base-features
 * @see http://stackoverflow.com/questions/8747005/backporting-nullptr-to-c-pre-c0x-programs
 * @ref cxx03-backports
 */
const std::nullptr_t nullptr = {};



#endif // using emulation

#endif // file



|







 







|
|







 







|
|
|
|
|
<








1
2
3
4
5
6
7
8
9
10
11
..
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
..
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
#ifndef CXXOMFORT_NULLPTR_HPP
#define CXXOMFORT_NULLPTR_HPP
/**
 * @file
 * @brief Implements @c nullptr as a comfort utility for C++03.
 * @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)
................................................................................
namespace std {

// This is pretty much borrowed from the Standards recommendation verbatim.

/**
 * @class nullptr_t
 * @brief Null pointer literal type.
 * @ingroup cxx11-backports
 * @ref base-features
 * 
 * @attention No variables of this type can be created.
 *
 * @c nullptr_t is defined in the C++0x Standard as the type of the
 * keyword "@c nullptr ", via decltype. In C++98 / C++03,
 * an emulation is provided and recommended by the Standard.
 *
................................................................................
};



} //~namespace std

/**
 * @brief Null pointer literal (backport)
 * @ingroup cxx11-backports
 * @see http://stackoverflow.com/questions/8747005/backporting-nullptr-to-c-pre-c0x-programs
 * @ref base-features
 * @ref cstddef

 */
const std::nullptr_t nullptr = {};



#endif // using emulation

#endif // file

Changes to cxxomfort/cxxomfort/base/static_assert.hpp.

1
2
3
4
5
6
7
8
9
10
11
..
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
#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
................................................................................
    && CXXOMFORT_COMPILER_VERSION >= 406)
#pragma GCC system_header
#endif


/**
 * @def static_assert

 * @ingroup base-features
 * @ref cxx03-backports
 * @brief Provides an assertion at compile-time
 * @param test The boolean test to run, must be computable at compile-time
 * @param msg The string literal to provide as a compiler error message if the assertion does not hold
 */
//    #define static_assert(test,msg) enum { CXXOMFORT_JOINX(sassert_e_,__COUNTER__) = (int)(msg[0])/(test) }
    #if defined(_MSC_VER)
    #define static_assert(test,msg) typedef void* CXXOMFORT_JOINX(sassert_expr_,__COUNTER__)[(test)?1:-1]



|







 







>
|
|







1
2
3
4
5
6
7
8
9
10
11
..
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#ifndef CXXOMFORT_SASSERT_HPP
#define CXXOMFORT_SASSERT_HPP
/**
 * @file
 * @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
................................................................................
    && CXXOMFORT_COMPILER_VERSION >= 406)
#pragma GCC system_header
#endif


/**
 * @def static_assert
 * @ingroup cxx11-backports
 * @ref base-features
 * @ref cstddef
 * @brief Provides an assertion at compile-time
 * @param test The boolean test to run, must be computable at compile-time
 * @param msg The string literal to provide as a compiler error message if the assertion does not hold
 */
//    #define static_assert(test,msg) enum { CXXOMFORT_JOINX(sassert_e_,__COUNTER__) = (int)(msg[0])/(test) }
    #if defined(_MSC_VER)
    #define static_assert(test,msg) typedef void* CXXOMFORT_JOINX(sassert_expr_,__COUNTER__)[(test)?1:-1]

Changes to cxxomfort/cxxomfort/config.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
...
368
369
370
371
372
373
374
375
376
377
378



379
380
381
382
383
384
385
#ifndef CXXOMFORT_CONFIG_HPP
#define CXXOMFORT_CONFIG_HPP
/**
 * @file cxxomfort/config.hpp
 * @brief Configuration file for cxxomfort-library.
 * @author Luis Machuca Bezzaza
 *
 * This file contains configuration macros used by the cxxomfort library
 * and it is not intended to be directly used.
 */

//! Library version and release date as YYYYMM
#define CXXOMFORT_DATE 201712
//! Defines the library version (WARNING: to be deprecated)
#define CXXOMFORT_VERSION 55

#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)
//! Year of the standard emulated when the compiler is in emulation mode.
#define CXXOMFORT_CXX_EMULATION 0

// Notices Mode
//#if !defined(CXXOMFORT_NOTICES)
//#define CXXOMFORT_NOTICES 0
//#endif

//
// This section detects the compiler type, major and minor version
// and assigns them for macros for easy evaluation.
//

#define CXXO_VALUE_COMPILER_GCC 101
#define CXXO_VALUE_COMPILER_DIGITALMARS 102
................................................................................
}
*/

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

//
// Library information
//
namespace cxxomfort {



//! Information about the library support
const struct info { 
    enum {
    //! library version
    version = CXXOMFORT_VERSION , 
    date = CXXOMFORT_DATE, 
    //! compiler identification code



|







|
|
|
|







 







<
<
<
<
<







 







|
<
<
|
>
>
>







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
...
363
364
365
366
367
368
369
370


371
372
373
374
375
376
377
378
379
380
381
#ifndef CXXOMFORT_CONFIG_HPP
#define CXXOMFORT_CONFIG_HPP
/**
 * @file
 * @brief Configuration file for cxxomfort-library.
 * @author Luis Machuca Bezzaza
 *
 * This file contains configuration macros used by the cxxomfort library
 * and it is not intended to be directly used.
 */

//! Library version and release date as YYYYMMDD
#define CXXOMFORT_DATE 20180701UL
//! Defines the library version (WARNING: to be deprecated)
#define CXXOMFORT_VERSION 60

#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)
//! Year of the standard emulated when the compiler is in emulation mode.
#define CXXOMFORT_CXX_EMULATION 0






//
// This section detects the compiler type, major and minor version
// and assigns them for macros for easy evaluation.
//

#define CXXO_VALUE_COMPILER_GCC 101
#define CXXO_VALUE_COMPILER_DIGITALMARS 102
................................................................................
}
*/

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

//! Namespace @c cxxomfort holds most features of the library.


namespace cxxomfort {
namespace cxxostd {}
namespace library {}

//! Information about the library support
const struct info { 
    enum {
    //! library version
    version = CXXOMFORT_VERSION , 
    date = CXXOMFORT_DATE, 
    //! compiler identification code

Changes to cxxomfort/cxxomfort/config/_has.hpp.

Changes to cxxomfort/cxxomfort/config/clang.hpp.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
..
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#define CXXO_WARNING(msg) CXXO_NOTICE_IMPL_( "cxxomfort warning: " msg)

#if defined(CXXOMFORT_NOTICES)
    #pragma CXXO_NOTICE("Found the Clang C++ Compiler.")
#endif

#undef  CXXO_COMPILER_SUPPORT_alignof
#define CXXO_COMPILER_SUPPORT_alignof 1
#undef  CXXO_COMPILER_SUPPORT_alignment_tools
#define CXXO_COMPILER_SUPPORT_alignment_tools __has_extension(cxx_alignas)
#undef  CXXO_COMPILER_SUPPORT_attribute
#define CXXO_COMPILER_SUPPORT_attribute __has_extension(cxx_attributes)
#undef  CXXO_COMPILER_SUPPORT_auto
#define CXXO_COMPILER_SUPPORT_auto __has_extension(cxx_auto_type)
#undef  CXXO_COMPILER_SUPPORT_constexpr
................................................................................
#undef  CXXO_COMPILER_SUPPORT_noexcept
#define CXXO_COMPILER_SUPPORT_noexcept __has_extension(cxx_noexcept)
#undef  CXXO_COMPILER_SUPPORT_nullptr
#define CXXO_COMPILER_SUPPORT_nullptr __has_extension(cxx_nullptr)
#undef  CXXO_COMPILER_SUPPORT_rvref
#define CXXO_COMPILER_SUPPORT_rvref (__has_extension(cxx_rvalue_references) * __has_extension(cxx_implicit_moves))
#undef  CXXO_COMPILER_SUPPORT_std_is_trivially
#define CXXO_COMPILER_SUPPORT_std_is_trivially (CXXOMFORT_CXX_STD < 2011)
#undef  CXXO_COMPILER_SUPPORT_static_assert
#define CXXO_COMPILER_SUPPORT_static_assert __has_extension(cxx_static_assert)
#undef  CXXO_COMPILER_SUPPORT_typeof
#define CXXO_COMPILER_SUPPORT_typeof 1
#undef  CXXO_COMPILER_SUPPORT_unique_ptr
#define CXXO_COMPILER_SUPPORT_unique_ptr (CXXOMFORT_CXX_STD >= 2011)
#undef  CXXO_COMPILER_SUPPORT_variadic







|







 







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
..
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#define CXXO_WARNING(msg) CXXO_NOTICE_IMPL_( "cxxomfort warning: " msg)

#if defined(CXXOMFORT_NOTICES)
    #pragma CXXO_NOTICE("Found the Clang C++ Compiler.")
#endif

#undef  CXXO_COMPILER_SUPPORT_alignof
#define CXXO_COMPILER_SUPPORT_alignof (CXXOMFORT_CXX_STD >= 2011)
#undef  CXXO_COMPILER_SUPPORT_alignment_tools
#define CXXO_COMPILER_SUPPORT_alignment_tools __has_extension(cxx_alignas)
#undef  CXXO_COMPILER_SUPPORT_attribute
#define CXXO_COMPILER_SUPPORT_attribute __has_extension(cxx_attributes)
#undef  CXXO_COMPILER_SUPPORT_auto
#define CXXO_COMPILER_SUPPORT_auto __has_extension(cxx_auto_type)
#undef  CXXO_COMPILER_SUPPORT_constexpr
................................................................................
#undef  CXXO_COMPILER_SUPPORT_noexcept
#define CXXO_COMPILER_SUPPORT_noexcept __has_extension(cxx_noexcept)
#undef  CXXO_COMPILER_SUPPORT_nullptr
#define CXXO_COMPILER_SUPPORT_nullptr __has_extension(cxx_nullptr)
#undef  CXXO_COMPILER_SUPPORT_rvref
#define CXXO_COMPILER_SUPPORT_rvref (__has_extension(cxx_rvalue_references) * __has_extension(cxx_implicit_moves))
#undef  CXXO_COMPILER_SUPPORT_std_is_trivially
#define CXXO_COMPILER_SUPPORT_std_is_trivially (CXXOMFORT_CXX_STD >= 2011)
#undef  CXXO_COMPILER_SUPPORT_static_assert
#define CXXO_COMPILER_SUPPORT_static_assert __has_extension(cxx_static_assert)
#undef  CXXO_COMPILER_SUPPORT_typeof
#define CXXO_COMPILER_SUPPORT_typeof 1
#undef  CXXO_COMPILER_SUPPORT_unique_ptr
#define CXXO_COMPILER_SUPPORT_unique_ptr (CXXOMFORT_CXX_STD >= 2011)
#undef  CXXO_COMPILER_SUPPORT_variadic

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

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

Changes to cxxomfort/cxxomfort/cstddef.hpp.

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

#include <cxxomfort/config.hpp>
#include <cxxomfort/base.hpp>
#include "base/nullptr.hpp"  // nullptr_t
#include "base/static_assert.hpp"
#include "impl/17-byte.hpp" // c++17's "byte"
#include CXXO_INCLUDE_SYS(cstddef)
#endif



|
|
|
<










1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
#ifndef CXXOMFORT_CSTDDEF_HPP
#define CXXOMFORT_CSTDDEF_HPP
/**
 * @file
 * @brief <cstddef> wrapper
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>

 *
 */

#include <cxxomfort/config.hpp>
#include <cxxomfort/base.hpp>
#include "base/nullptr.hpp"  // nullptr_t
#include "base/static_assert.hpp"
#include "impl/17-byte.hpp" // c++17's "byte"
#include CXXO_INCLUDE_SYS(cstddef)
#endif

Changes to 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



|
|
|
|












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
 * @brief <cstdint> wrapper
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 * @anchor cstdint
 *
 */

#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.

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
..
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
#ifndef CXXOMFORT_HPP
#define CXXOMFORT_HPP
/**
 * @file cxxomfort.hpp
 * @brief Header file for C++11 and onward backport utilities.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 * @license MIT License (see LICENSE.txt)
 * @mainpage Cxxomfort Tools for C++03.
 *
 * Cxxomfort is a small, header-only library that backports to C++03
 * some of the nifty C++11 goodies. I wrote it 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.
 *
 * Information on features and usage is available at the repository's page:
 *
 * http://ryan.gulix.cl/fossil.cgi/cxxomfort
 *
 * This library is distributed under the terms of the
 * MIT License. Check LICENSE.txt for more information.
 * 
 * See:
 * 
 * * @subpage base-features "Base Features"
 * * @subpage independent-features "Independent Features"
 * * @subpage extra-features "Extras"
 * * @subpage transparent-headers "Transparent Headers"
 * * @ref cxx03-backports
 * * @ref cxx11-backports
 * * @ref cxx14-backports
 * 
 * Some features are matched to the C++ @b headers  
 * they are provided in in Standard C++:



 * 
 * * @subpage algorithm "<algorithm>"
 * * @subpage cstddef "<cstddef>"
 * * @subpage forward_list "<forward_list>"
 * * @subpage functional "<functional>"
 * * @subpage iterator "<iterator>"
 * * @subpage memory "<memory>"
 * * @subpage random "<random>"
 * * @subpage string "<string>"
 * * @subpage utility "<utility>"
 * * @subpage tuple "<tuple>"
 * * @subpage type_traits "<type_traits>"

 * 

 *




 */

//
// Setup
#include "config.hpp"

//
................................................................................
#include "algorithm.hpp" // <algorithm> additions (copy_if, minmax, etc...)
#include "cstddef.hpp" // <cstddef> additions (byte, nullptr, etc...)
#include "cstdint.hpp" // <cstdint> wrapper (integer types)
#include "forward_list.hpp" // <forward_list>
#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 "random.hpp" // <random> additions (rename fixes, std::random_device, etc...)
#include "string.hpp" // string function helpers (eg.: to_string)
#include "tuple.hpp" // tuple helpers, tuple get<type>, ...
#include "type_traits.hpp" // common_type, decay, is_literal, is_null_pointer, etc...
#include "utility.hpp" // declval, exchange, pair...
#include "library.hpp" // cxxomfort library features
#include "sequences.hpp" // sequence helpers, seq_<T>()
#include "util/type_traits.hpp" // basic type_traits
#include "impl/regex-esc.hpp" // CXXO_R for raw regex patterns

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






 */

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











 */













































#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
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
..
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
#ifndef CXXOMFORT_HPP
#define CXXOMFORT_HPP
/**
 * @file cxxomfort.hpp
 * @brief Backports library for C++.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 * @license MIT License (see LICENSE.txt)
 * @mainpage Cxxomfort Backport Tools for C++.
 *
 * Cxxomfort is a small, header-only library that backports nifty features and goodies from C++11 and later versions to previous versions such as C++03, as well as featuring some proposals still in the works. It was written to facilitate working with the evolving C++ Standard when I was coming back to the language during the C++11 transition, as well as reduce stress of code rewrite while at the same time assisting in backwards and forwards portability.




 * 
 * Information on features and usage is available at the repository's page:
 *
 * http://ryan.gulix.cl/fossil.cgi/cxxomfort
 *
 * This library is distributed under the terms of the
 * MIT License. Check LICENSE.txt for more information.
 * 
 * 
 * The library is organized in two ways:
 * 
 * First, the various features are organized depending on the C++ version they derive from:
 * 
 * * @subpage cxx03-backports
 * * @subpage cxx11-backports
 * * @subpage cxx14-backports
 * * @subpage cxx17-backports
 * * @subpage cxx20-backports
 * * @ref independent-features "Independent Features"
 * * @ref extra-features "Extras"
 * * @ref transparent-headers "Transparent Headers"
 * 
 * Second, they are organized according to the C++ Standard Header they were implemented from:
 * 
 * * @subpage algorithm "<algorithm>"
 * * @subpage cstddef "<cstddef>"
 * * @subpage forward_list "<forward_list>"
 * * @subpage functional "<functional>"
 * * @subpage iterator "<iterator>"
 * * @subpage memory "<memory>"
 * * @subpage random "<random>"
 * * @subpage string "<string>"

 * * @subpage tuple "<tuple>"
 * * @subpage type_traits "<type_traits>"
 * * @subpage utility "<utility>"
 * 
 * The library features not only backports however; it also offers its own features and emulations up to and including its own @c string type (because who in C++ ever doesn't write one).
 * 
 * * @ref independent-features "Independent Features"
 *
 * For installation see @ref cxxomfort-installation "Installation" ; for general usage see @ref cxxomfort-usage "Usage" .
 * 
 */

//
// Setup
#include "config.hpp"

//
................................................................................
#include "algorithm.hpp" // <algorithm> additions (copy_if, minmax, etc...)
#include "cstddef.hpp" // <cstddef> additions (byte, nullptr, etc...)
#include "cstdint.hpp" // <cstdint> wrapper (integer types)
#include "forward_list.hpp" // <forward_list>
#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 "numeric.hpp" // <numeric> stuff like iota
#include "random.hpp" // <random> additions (rename fixes, std::random_device, etc...)
#include "string.hpp" // string function helpers (eg.: to_string)
#include "tuple.hpp" // tuple helpers, tuple get<type>, ...
#include "type_traits.hpp" // common_type, decay, is_literal, is_null_pointer, etc...
#include "utility.hpp" // declval, exchange, pair...
#include "library.hpp" // cxxomfort library features
#include "sequences.hpp" // sequence helpers, seq_<T>()
#include "util/type_traits.hpp" // basic type_traits
#include "impl/regex-esc.hpp" // CXXO_R for raw regex patterns

/**
 * @page cxx03-backports
 * @brief Backports from C++03.
 * 
 * A listing of some of the features backported:
 * 
 * * From <code><functional></code>: @ref bind1st etc.
 * 
*
 */

/**
 * @page cxx11-backports

 * @brief Backports from C++11.
 * 
 * C++11 adds a large number of features such as variadic templates, @c constexpr , static asserts and much improved template support and metaprogramming.
 * 
 * A listing of some of the features backported:
 * 
 * * From <code><algorithm></code>: copy_if(), copy_n(), partition_copy(), minmax(), minmax_element(), etc.
 * * From <code><string></code>: to_string() , etc.
 * * From <code><utility></code>: declval() , etc.
 * 
 * See also: @ref cxx14-backports .
 */

/**
 * @page cxx14-backports
 * @brief Backports from C++14.
 * 
 * C++14 adds a number of features regarding algorithms and function object support.
 * 
 * A listing of some of the features backported:
 * 
 * * From <code><algorithm></code>: equal(), mismatch(), etc.
 * * From <code><functional></code>: @link Transparent Functors @endlink .
 * * From <code><utility></code>: exchange() , std::integer_sequence , etc.
 * 
 * See also: @ref cxx17-backports .
 */

/**
 * @page cxx17-backports
 * @brief Backports from C++17.
 * 
 * A listing of some of the features backported:
 * 
 * * From <code><type_traits></code>: std::void_t, etc.
 * * From <code><utility></code>: as_const(), etc.
 * 
 * See also: @ref cxx20-backports .
 */

/**
 * @page cxx20-backports
 * @brief Backports from C++20.
 * 
 * A listing of some of the features backported:
 * 
 * * TBD
 * * From <code><utility></code>: as_const(), etc. 
 *
 * 
 */

/**
 * @page extra-features
 * @brief Non-automatic features of cxxomfort.
 */

#endif

Changes to cxxomfort/cxxomfort/extras/14-assert.hpp.

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

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
namespace cxxomfort {
namespace extras {
namespace array_ref {

/**
 * @brief Array view for sequences, from n3334
 * @anchor array_ref
 * @addtogroup extra-features
 * @sa n3334
 * 
 * A @c array_ref is a non-owning view of a sequence of 
 * *contiguous* elements via a simple {pointer+length} package.
 * 
 * It provides some of the same operatios available for readable
 * sequences, in particular begin() and end().







|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
namespace cxxomfort {
namespace extras {
namespace array_ref {

/**
 * @brief Array view for sequences, from n3334
 * @anchor array_ref
 * @ingroup extra-features
 * @sa n3334
 * 
 * A @c array_ref is a non-owning view of a sequence of 
 * *contiguous* elements via a simple {pointer+length} package.
 * 
 * It provides some of the same operatios available for readable
 * sequences, in particular begin() and end().

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

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

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

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
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
...
326
327
328
329
330
331
332
333
334
335
336
337
    explicit dynarray (size_type N);     ///< (1) count-constructor
    dynarray (size_type N, T const& v);  ///< (3) count-constructor
    dynarray (dynarray const &V);        ///< (5) copy-constructor
    /// iterator-constructor
    template <typename It>
    dynarray (It ini, It fin, typename std::enable_if<is_iterator<It>::value,bool>::type* = nullptr);
    
    ////! Inicializa un vector de una lista esttica en C++11
#if (CXXOMFORT_CXX_STD >= 2011) || defined(DOXYGEN_DOC)
    dynarray (std::initializer_list<T> const&) CXXO_NOEXCEPT;             ///< (7) initializer_list-ctor
#endif

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

    ~dynarray ();                                 ///< destructor
................................................................................
    T*              data () CXXO_NOEXCEPT { return m_p; } // nothrow

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

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

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

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

    const_reverse_iterator     rbegin () const CXXO_NOEXCEPT {
        return const_reverse_iterator(this->end());
    }
    reverse_iterator     rbegin () CXXO_NOEXCEPT {
        return reverse_iterator(this->end());
................................................................................
#undef _DELETED_

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

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

#endif







|







 







|









|













|




|







 







|




122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
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
...
326
327
328
329
330
331
332
333
334
335
336
337
    explicit dynarray (size_type N);     ///< (1) count-constructor
    dynarray (size_type N, T const& v);  ///< (3) count-constructor
    dynarray (dynarray const &V);        ///< (5) copy-constructor
    /// iterator-constructor
    template <typename It>
    dynarray (It ini, It fin, typename std::enable_if<is_iterator<It>::value,bool>::type* = nullptr);
    
    ////! Inicializa un vector de una lista estática en C++11
#if (CXXOMFORT_CXX_STD >= 2011) || defined(DOXYGEN_DOC)
    dynarray (std::initializer_list<T> const&) CXXO_NOEXCEPT;             ///< (7) initializer_list-ctor
#endif

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

    ~dynarray ();                                 ///< destructor
................................................................................
    T*              data () CXXO_NOEXCEPT { return m_p; } // nothrow

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

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

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

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

    const_reverse_iterator     rbegin () const CXXO_NOEXCEPT {
        return const_reverse_iterator(this->end());
    }
    reverse_iterator     rbegin () CXXO_NOEXCEPT {
        return reverse_iterator(this->end());
................................................................................
#undef _DELETED_

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

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

#endif

Changes to cxxomfort/cxxomfort/extras/observer_ptr.hpp.

23
24
25
26
27
28
29


30
31
32
33
34
35
36

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
 * 







>
>







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

namespace cxxomfort {
namespace extras {
namespace observer_ptr {

/**
 * @brief observer_ptr - the world's dumbest smart pointer
 * @ingroup extra-features
 * @ref memory
 * 
 * @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
 * 

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

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
...
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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) {}

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


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

    //! 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();







|







 







|







 







|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
...
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
class optional_impl {
    static_assert (!std::is_lvalue_reference<T>::value, "optional<T>: T must not be a reference type");
    static_assert ((!std::is_same<T,nullopt_t>::value), "optional<T>: T must not be an optional 'nullopt' tag");
    

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

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


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

    T     value_or (T const& alt) const CXXO_NOEXCEPT {
        if (!_engaged) return alt;
................................................................................
    }

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

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

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

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

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

168
169
170
171
172
173
174


175
176
177
178
179

180
181
182
183
184
185
186
    }
    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







>
>
|




>







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    }
    optional& operator= (nullopt_t) CXXO_NOEXCEPT {
        ((base_type*)this)->operator= (nullopt);
        return *this;
    }
#endif

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

    // unchecked access

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

    // checked access

Changes to cxxomfort/cxxomfort/forward_list.hpp.

1
2
3
4
5
6
7
8
9
10
11
..
79
80
81
82
83
84
85


86

87
88
89
90
91
92
93
...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
...
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
...
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
#ifndef CXXOMFORT_FORWARD_LIST_HPP
#define CXXOMFORT_FORWARD_LIST_HPP
/**
 * @file cxxomfort/extras/forward_list.hpp
 * @brief Implements C++11's "forward_list" in C++03.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces defined in this header:
 *
 * * forward_list (from C++11)
 *
................................................................................
    typedef detail_fwlist::iterator_base<T,false>    iterator;
    typedef detail_fwlist::iterator_base<T,true>     const_iterator;

    private:
    CXXO_COPYABLE_MOVABLE(forward_list);

    public:


    forward_list () CXXO_NOEXCEPT;                //< default-ctor

    forward_list (forward_list const&);           //< copy-ctor
    forward_list (forward_list const&, A const&); //< realloc copy constructor
    
    explicit forward_list
    (size_t, T const& t= T(), A const& a = A());  //< element-ctor
    
    template <typename I> forward_list
................................................................................
    void  assign (Iterator,Iterator);   //< assign a sequence
    
#if (CXXOMFORT_CXX_STD >= 2011)
    forward_list& operator= (std::initializer_list<T> const&);        //< init-list assignment
    void  assign (std::initializer_list<T> const&);    //< assign a init-list
#endif

    // Get Info
    ////////
    
    allocator_type  get_allocator () const;  //< direct access to allocator
    bool       empty () const;          //< check if empty
    size_type  max_size () const;       //< max size

    // Access
    ////////

    const_reference front () const;     //< direct access to front
    reference       front ();           //< direct access to front
    
    const_iterator  cbegin () const CXXO_NOEXCEPT;     //< read-only iteration from begin
    const_iterator  begin ()  const CXXO_NOEXCEPT { return cbegin(); }
    const_iterator  cend ()   const CXXO_NOEXCEPT;     //< read-only iteration mark end
................................................................................
    iterator   insert_after (const_iterator, T const&);          //< insert
    iterator   insert_after (const_iterator, CXXO_RV_REF(T));    //< insert (by move)
    iterator   insert_after (const_iterator, size_type, T const&);    //< insert multiple copies
    template< class I >
    iterator   insert_after (const_iterator pos, I ini, I fin);  //< insert a sequence
#if (CXXOMFORT_CXX_STD >= 2011)
    iterator   insert_after (const_iterator, std::initializer_list<T> const&);         //< insert a init-list
#else
    CXXO_PSEUDOVARIADIC_MEMBER(void , emplace_front , ); //< emplace-insertion at the front






    // Deletions
    ////////
    
    void  pop_front ();                 //< erase at begin
    iterator   erase_after (const_iterator);           //< erase after position
    iterator   erase_after (const_iterator, const_iterator);     //< erase a sequence of elements
    
    void       clear ();                //< erase everything - return to defaulted state



#endif

    // emplace_after( p, ...)

    // Sort
    ////////
    
    void  sort ();
    template <typename Compare>
................................................................................

    void  unique ();
    template <typename Compare>
    void  unique (Compare);
#endif

    private:
    node_t          _p_bb, *_p_last;

    node_alloc_t    alloc;

    static nodeT_t *N (node_t* p) { return static_cast<nodeT_t*>(p); }
    static node_t  *U (nodeT_t *p) { return static_cast<node_t*>(p); }

    node_t*    insert_after (node_t *p, T const&);
    node_t*    in_unlink_after (node_t *p);
................................................................................

    template <typename I> void in_uninitialized_copy(I,I);

    void            in_uninitialized_fill_n (size_t, T const&);
    void            in_link_after (node_t*, node_t*);
    void            in_readjust_last ();
    node_t*    in_destroy (nodeT_t*);


} /* forward_list */ ;

template <typename T1, typename A1, typename T2, typename A2>
bool operator== (forward_list<T1,A1> const& a, forward_list<T2,A2> const& b);

template <typename T1, typename A1, typename T2, typename A2>



|







 







>
>
|
>







 







<
<
<




<
<







 







|
<
>
>
>
>
>




|






<
<
<







 







|
>







 







>







1
2
3
4
5
6
7
8
9
10
11
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
115
116
117
118
119
120
121



122
123
124
125


126
127
128
129
130
131
132
...
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
...
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
#ifndef CXXOMFORT_FORWARD_LIST_HPP
#define CXXOMFORT_FORWARD_LIST_HPP
/**
 * @file
 * @brief Implements C++11's "forward_list" in C++03.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces defined in this header:
 *
 * * forward_list (from C++11)
 *
................................................................................
    typedef detail_fwlist::iterator_base<T,false>    iterator;
    typedef detail_fwlist::iterator_base<T,true>     const_iterator;

    private:
    CXXO_COPYABLE_MOVABLE(forward_list);

    public:
    
    // constructors
    forward_list () CXXO_NOEXCEPT;                //< default-ctor
    forward_list (A const&); 
    forward_list (forward_list const&);           //< copy-ctor
    forward_list (forward_list const&, A const&); //< realloc copy constructor
    
    explicit forward_list
    (size_t, T const& t= T(), A const& a = A());  //< element-ctor
    
    template <typename I> forward_list
................................................................................
    void  assign (Iterator,Iterator);   //< assign a sequence
    
#if (CXXOMFORT_CXX_STD >= 2011)
    forward_list& operator= (std::initializer_list<T> const&);        //< init-list assignment
    void  assign (std::initializer_list<T> const&);    //< assign a init-list
#endif




    allocator_type  get_allocator () const;  //< direct access to allocator
    bool       empty () const;          //< check if empty
    size_type  max_size () const;       //< max size




    const_reference front () const;     //< direct access to front
    reference       front ();           //< direct access to front
    
    const_iterator  cbegin () const CXXO_NOEXCEPT;     //< read-only iteration from begin
    const_iterator  begin ()  const CXXO_NOEXCEPT { return cbegin(); }
    const_iterator  cend ()   const CXXO_NOEXCEPT;     //< read-only iteration mark end
................................................................................
    iterator   insert_after (const_iterator, T const&);          //< insert
    iterator   insert_after (const_iterator, CXXO_RV_REF(T));    //< insert (by move)
    iterator   insert_after (const_iterator, size_type, T const&);    //< insert multiple copies
    template< class I >
    iterator   insert_after (const_iterator pos, I ini, I fin);  //< insert a sequence
#if (CXXOMFORT_CXX_STD >= 2011)
    iterator   insert_after (const_iterator, std::initializer_list<T> const&);         //< insert a init-list
#endif


#if (CXXOMFORT_CXX_STD >= 2011)
    template <typename... Args>
    iterator emplace_after (iterator, Args&&...);
#endif

    // Deletions
    ////////
    
    void  pop_front ();                 //< erase element at the front
    iterator   erase_after (const_iterator);           //< erase after position
    iterator   erase_after (const_iterator, const_iterator);     //< erase a sequence of elements
    
    void       clear ();                //< erase everything - return to defaulted state





    // emplace_after( p, ...)

    // Sort
    ////////
    
    void  sort ();
    template <typename Compare>
................................................................................

    void  unique ();
    template <typename Compare>
    void  unique (Compare);
#endif

    private:
    node_t          _p_bb;
    node_t *_p_last;
    node_alloc_t    alloc;

    static nodeT_t *N (node_t* p) { return static_cast<nodeT_t*>(p); }
    static node_t  *U (nodeT_t *p) { return static_cast<node_t*>(p); }

    node_t*    insert_after (node_t *p, T const&);
    node_t*    in_unlink_after (node_t *p);
................................................................................

    template <typename I> void in_uninitialized_copy(I,I);

    void            in_uninitialized_fill_n (size_t, T const&);
    void            in_link_after (node_t*, node_t*);
    void            in_readjust_last ();
    node_t*    in_destroy (nodeT_t*);
    void       in_report_list ();

} /* forward_list */ ;

template <typename T1, typename A1, typename T2, typename A2>
bool operator== (forward_list<T1,A1> const& a, forward_list<T2,A2> const& b);

template <typename T1, typename A1, typename T2, typename A2>

Changes to cxxomfort/cxxomfort/functional.hpp.

1
2
3
4
5
6
7
8
9
10
11
12
..
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34
35
36

37
38

39
40
#ifndef CXXOMFORT_FUNCTIONAL_HPP
#define CXXOMFORT_FUNCTIONAL_HPP

/**
 * @file functional.hpp
 * @brief Implementations and additions tied to <functional>.
 * 
 * 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.
 *
................................................................................
#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
 * @{
 */


/**
 * @}
 */


#include "./impl/14-functional-transparent.hpp"
//#include "./impl/17-notfn.hpp"


#endif




|







 







<
>
>
|
<
<
|
|
<
<
<

>


>


1
2
3
4
5
6
7
8
9
10
11
12
..
20
21
22
23
24
25
26

27
28
29


30
31



32
33
34
35
36
37
38
#ifndef CXXOMFORT_FUNCTIONAL_HPP
#define CXXOMFORT_FUNCTIONAL_HPP

/**
 * @file cxxomfort/functional.hpp
 * @brief Implementations and additions tied to <functional>.
 * 
 * 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.
 *
................................................................................
#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


namespace cxxomfort {
//! @brief Components related to <functional>
namespace functional {


}
}





#include "./impl/14-functional-transparent.hpp"
//#include "./impl/17-notfn.hpp"
//#include "./impl/03-restore_binders.hpp"

#endif

Changes to 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


>
>
>
|
>








<
<
<
<

|




|




|









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
/**
 * @file
 * @brief c++03 fixes to <functional> in incomplete implementations
 * 
 */
#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 {






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

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

//! @ingroup 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

Changes to 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
#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) {}
};


>
>
>





|





>











>








>







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
#ifndef CXXOMFORT_IMPL_RANDOM_RENAMES_HPP
#define CXXOMFORT_IMPL_RANDOM_RENAMES_HPP
/**
 * @file
 */

#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) || (defined(DOXYGEN_DOC)))
namespace std {
namespace tr1 {

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

//! @ingroup cxx11-backports
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;

//! @ingroup cxx11-backports
template <typename II>
class uniform_int_distribution
: public uniform_int<II> {
    public:
    uniform_int_distribution(II a, II b)
    : uniform_int<II>(a,b) {}
};

//! @ingroup cxx11-backports
template <typename Real>
class uniform_real_distribution
: public uniform_real<Real> {
    public:
    uniform_real_distribution(Real a, Real b)
    : uniform_real<Real>(a,b) {}
};

Changes to cxxomfort/cxxomfort/impl/11-addressof.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
#ifndef CXXOMFORT_IMPL_ADDRESSOF_HPP
#define CXXOMFORT_IMPL_ADDRESSOF_HPP
/**
 * @file addressof.hpp
 * @brief Implements std::addressof in C++03.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 */

#include "../config.hpp"

#if (CXXOMFORT_CXX_STD < 2011 && CXXOMFORT_CXX_EMULATION==0)
    #define CXXOMFORT_USING_addressof
#endif // c++11

namespace cxxomfort {






template <typename T> inline
T* addressof (T& arg) {
    return reinterpret_cast<T*>(&reinterpret_cast<char&> (arg) );
}

//! @overloads addressof
template <typename T> inline
T const* addressof (T const& arg) {
    return reinterpret_cast<T const*>(&reinterpret_cast<char const&> (arg) );
}


} // cxxomfort


#if defined(CXXOMFORT_USING_addressof)

namespace std {
    using ::cxxomfort::addressof;
}

#else
    // nothing to do
#endif

#endif // file



|












>
|
>
>
>
>





|





>






|







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
#ifndef CXXOMFORT_IMPL_ADDRESSOF_HPP
#define CXXOMFORT_IMPL_ADDRESSOF_HPP
/**
 * @file
 * @brief Implements std::addressof in C++03.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 */

#include "../config.hpp"

#if (CXXOMFORT_CXX_STD < 2011 && CXXOMFORT_CXX_EMULATION==0)
    #define CXXOMFORT_USING_addressof
#endif // c++11

namespace cxxomfort {
namespace memory {

/**
 * @brief Returns the address of an object.
 * @ingroup cxx11-backports
 */
template <typename T> inline
T* addressof (T& arg) {
    return reinterpret_cast<T*>(&reinterpret_cast<char&> (arg) );
}

//! @overload addressof
template <typename T> inline
T const* addressof (T const& arg) {
    return reinterpret_cast<T const*>(&reinterpret_cast<char const&> (arg) );
}

} // memory
} // cxxomfort


#if defined(CXXOMFORT_USING_addressof)

namespace std {
    using ::cxxomfort::memory::addressof;
}

#else
    // nothing to do
#endif

#endif // file

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

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

21
22
23

24
25
26
27
28
29
30
..
68
69
70
71
72
73
74

75
76
77
78
#ifndef CXXOMFORT_IMPL_ALIGNED_STORAGE_HPP
#define CXXOMFORT_IMPL_ALIGNED_STORAGE_HPP
/**
 * @file aligned_storage.hpp
 * @brief Implements std::aligned_storage in C++03 (partial).
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 */

#include "../config.hpp"

................................................................................
 * That however is an intrinsic, so it has to be detected on a per-compiler basis.
 * For compilers without __alignof(), we can usually do "well enough" by reserving 
 * [2*sizeof(T)+1] for compound types, and [sizeof(T)] for fundamental types.
 */


namespace cxxomfort {


#if 0

#elif (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC)

    #if (CXXOMFORT_COMPILER_VERSION<=406) // align(N) can only take literals

template <size_t S, size_t A = -1> struct aligned_storage;
#define ALIGNED_STORAGE_ALIGN(N) \
template <size_t S> struct aligned_storage<S, N > { \
    typedef struct { unsigned char __attribute__((aligned( N ))) elem[S]; } type; \
}
................................................................................
#define CXXO_DEFINED_ALIGNED_STORAGE

#else // unrecognized compiler
#error "Unknown support status for aligned_storage"

#endif // support for aligned_storage


} // cxxomfort


#endif // file



|







 







<
>
|
|
|
>







 







>




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

20
21
22
23
24
25
26
27
28
29
30
31
..
69
70
71
72
73
74
75
76
77
78
79
80
#ifndef CXXOMFORT_IMPL_ALIGNED_STORAGE_HPP
#define CXXOMFORT_IMPL_ALIGNED_STORAGE_HPP
/**
 * @file
 * @brief Implements std::aligned_storage in C++03 (partial).
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 */

#include "../config.hpp"

................................................................................
 * That however is an intrinsic, so it has to be detected on a per-compiler basis.
 * For compilers without __alignof(), we can usually do "well enough" by reserving 
 * [2*sizeof(T)+1] for compound types, and [sizeof(T)] for fundamental types.
 */


namespace cxxomfort {

namespace memory {
#if 0

#elif (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC) \
 || (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_CLANG)
    #if (CXXOMFORT_COMPILER_VERSION<=406) // align(N) can only take literals

template <size_t S, size_t A = -1> struct aligned_storage;
#define ALIGNED_STORAGE_ALIGN(N) \
template <size_t S> struct aligned_storage<S, N > { \
    typedef struct { unsigned char __attribute__((aligned( N ))) elem[S]; } type; \
}
................................................................................
#define CXXO_DEFINED_ALIGNED_STORAGE

#else // unrecognized compiler
#error "Unknown support status for aligned_storage"

#endif // support for aligned_storage

} // memory
} // cxxomfort


#endif // file

Added cxxomfort/cxxomfort/impl/11-conditional.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
#ifndef CXXOMFORT_IMPL_CONDITIONAL_HPP
#define CXXOMFORT_IMPL_CONDITIONAL_HPP
/**
 * @file
 * @brief Implements std::enable_if , std::conditional in C++03.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 */

#include "../config.hpp"

#if (CXXOMFORT_CXX_STD < 2011)
    #define CXXOMFORT_USING_conditional

namespace cxxomfort {
namespace type_traits {

template <bool B, typename T=void>
struct enable_if{};

template <typename T>
struct enable_if<true, T> {
    typedef T type;
};

template <bool B, typename T, typename U>
struct conditional {};

template <typename T, typename U>
struct conditional<false,T,U> { typedef U type; };

template <typename T, typename U>
struct conditional<true,T,U> { typedef T type; };

} // type_traits
} // cxxomfort


namespace std {
    using ::cxxomfort::type_traits::enable_if;
    using ::cxxomfort::type_traits::conditional;
}

#endif
#endif // file

Changes to cxxomfort/cxxomfort/impl/11-is_xxx_of.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
#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 {

/**
 * @brief Returns @c true  if all elements in sequence <var>[ini,fin)</var> comply with predicate @p p .
 * @ingroup algorithm
 * @ref cxx03-backports








 */
template< class Iterator, class Predicate >
bool all_of(Iterator ini, Iterator fin, Predicate p) {
    for (; ini != fin; ++ini) {
        if (!p(*ini)) return false;
    }
    return true;
}

/**
 * @brief Returns @c true  if at least one element in sequence <var>[ini,fin)</var> comply with predicate @p p .
 * @ingroup algorithm
 * @ref cxx03-backports
 */
template< class Iterator, class Predicate >
bool any_of(Iterator ini, Iterator fin, Predicate p) {
    for (; ini != fin; ++ini) {
        if (p(*ini)) return true;
    }
    return true;
}

/**
 * @brief Returns @c true  if no elements in sequence <var>[ini,fin)</var> comply with predicate @p p .
 * @ingroup algorithm
 * @ref cxx03-backports 
 */
template< class Iterator, class Predicate >
bool none_of(Iterator ini, Iterator fin, Predicate p) {
    for (; ini != fin; ++ini) {
        if (p(*ini)) return false;
    }
    return true;
}





} // cxxomfort::algo
} // cxxomfort

// These were added in c++11

#if (!defined(CXXOMFORT_NO_STD_USING))
#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;


>
>
>




<
<
<




<

|
>
>
>
>
>
>
>
>











|
<











|
<









>
>
>
>
|


<
>







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
#ifndef CXXOMFORT_IMPL_IS_OF_HPP
#define CXXOMFORT_IMPL_IS_OF_HPP
/**
 * @file
 */

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




namespace cxxomfort {
namespace algorithm {

/**

 * @ingroup algorithm
 * @ingroup cxx11-backports
 * @sa n2569
 * @{
 */

/**
 * @brief Returns @c true  if all elements in sequence <var>[ini,fin)</var> comply with predicate @p p .
 * @param p A predicate (a function that returns @c true or @c false ).
 * 
 */
template< class Iterator, class Predicate >
bool all_of(Iterator ini, Iterator fin, Predicate p) {
    for (; ini != fin; ++ini) {
        if (!p(*ini)) return false;
    }
    return true;
}

/**
 * @brief Returns @c true  if at least one element in sequence <var>[ini,fin)</var> comply with predicate @p p .
 * @param p A predicate (a function that returns @c true or @c false ).

 */
template< class Iterator, class Predicate >
bool any_of(Iterator ini, Iterator fin, Predicate p) {
    for (; ini != fin; ++ini) {
        if (p(*ini)) return true;
    }
    return true;
}

/**
 * @brief Returns @c true  if no elements in sequence <var>[ini,fin)</var> comply with predicate @p p .
 * @param p A predicate (a function that returns @c true or @c false ).

 */
template< class Iterator, class Predicate >
bool none_of(Iterator ini, Iterator fin, Predicate p) {
    for (; ini != fin; ++ini) {
        if (p(*ini)) return false;
    }
    return true;
}

/**
 * @}
 */

} // cxxomfort::algorithm
} // cxxomfort



#if (!defined(CXXOMFORT_NO_STD_USING))
#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;

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

1
2
3


4
5
6
7
8
9
10
..
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#ifndef CXXOMFORT_IMPL_PERMUTATIONS_HPP
#define CXXOMFORT_IMPL_PERMUTATIONS_HPP



#include <algorithm>
#include <utility>

namespace cxxomfort {
namespace algorithm {

/* Returns true if range [iniA,finA] (with internally calculated finA) 
................................................................................
    std::less<typename std::iterator_traits<BidirIt>::value_type> less;
    return prev_permutation(ini, fin, less);
}

} // cxxomfort::algo
} // cxxomfort

// These were added in c++11
#if (!defined(CXXOMFORT_NO_STD_USING))
#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;


|
>
>







 







<







1
2
3
4
5
6
7
8
9
10
11
12
..
93
94
95
96
97
98
99

100
101
102
103
104
105
106
#ifndef CXXOMFORT_IMPL_PERMUTATIONS_HPP
#define CXXOMFORT_IMPL_PERMUTATIONS_HPP
/**
 * @file
 */
#include <algorithm>
#include <utility>

namespace cxxomfort {
namespace algorithm {

/* Returns true if range [iniA,finA] (with internally calculated finA) 
................................................................................
    std::less<typename std::iterator_traits<BidirIt>::value_type> less;
    return prev_permutation(ini, fin, less);
}

} // cxxomfort::algo
} // cxxomfort


#if (!defined(CXXOMFORT_NO_STD_USING))
#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;

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

1
2
3
4
5
6
7
8
9
10
11
..
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
...
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
#ifndef CXXOMFORT_IMPL_STRING_HPP
#define CXXOMFORT_IMPL_STRING_HPP
/**
 * @file impl/11-to_string.hpp
 * @brief Implements the "to_string" functionality.
 *
 * This file implements the template function "to_string", 
 * which converts a builtin integral type to a decimal representation 
 * in a @c std::string , and the template functions "stoul" and "stoi" which 
 * perform the inverse function.
 * 
................................................................................
 * 
 * This version of "to_string" has only support for integral types, 
 * eg.: @c int , @c short and similar. Floating-point type support 
 * or wstring support are not yet available.
 * 
 */

#include <cxxomfort/cxxomfort.hpp>

#include <string>
#include <cstdio>
#include <cstdlib>
#include <stdlib.h> // for MSVC?
#include <stdexcept>
#include <limits>
#include <vector>
................................................................................
#include <cerrno>

#if (CXXOMFORT_CXX_STD >= 2011)
#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

................................................................................
};


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



|







 







|
>







 







|







 







>
|
<
|
<



|



|



|



|



|



|



|



|



|



|







1
2
3
4
5
6
7
8
9
10
11
..
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
...
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
#ifndef CXXOMFORT_IMPL_STRING_HPP
#define CXXOMFORT_IMPL_STRING_HPP
/**
 * @file
 * @brief Implements the "to_string" functionality.
 *
 * This file implements the template function "to_string", 
 * which converts a builtin integral type to a decimal representation 
 * in a @c std::string , and the template functions "stoul" and "stoi" which 
 * perform the inverse function.
 * 
................................................................................
 * 
 * This version of "to_string" has only support for integral types, 
 * eg.: @c int , @c short and similar. Floating-point type support 
 * or wstring support are not yet available.
 * 
 */

#include <cxxomfort/base.hpp>
#include <cxxomfort/util/type_traits.hpp> // is_arithmetic w/o C++11 dependency
#include <string>
#include <cstdio>
#include <cstdlib>
#include <stdlib.h> // for MSVC?
#include <stdexcept>
#include <limits>
#include <vector>
................................................................................
#include <cerrno>

#if (CXXOMFORT_CXX_STD >= 2011)
#else
    #define CXXOMFORT_USING_to_string
#endif

#if (defined(CXXOMFORT_USING_to_string) || defined(DOXYGEN_DOC))

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

................................................................................
};


} //cxxomfort::string::detail_string


/**
 * @brief Returns a @c string expression of an integral.
 * @ingroup cxx11-backports

 */

static inline std::string to_string (unsigned short u) {
    return detail_string::stringexpr(u);
}
//! @overload to_string
static inline std::string to_string (long long i) {
    return detail_string::stringexpr(i);
}
//! @overload to_string
static inline std::string to_string (unsigned long long u) {
    return detail_string::stringexpr(u);
}
//! @overload to_string
static inline std::string to_string (long double i) {
    return detail_string::stringexpr(i);
}
//! @overload to_string
static inline std::string to_string (unsigned int u) {
    return detail_string::stringexpr(u);
}
//! @overload to_string
static inline std::string to_string (short i) {
    return detail_string::stringexpr(i);
}
//! @overload to_string
static inline std::string to_string (long i) {
    return detail_string::stringexpr(i);
}
//! @overload to_string
static inline std::string to_string (int i) {
    return detail_string::stringexpr(i);
}
//! @overload to_string
static inline std::string to_string (unsigned long u) {
    return detail_string::stringexpr(u);
}
//! @overload to_string
static inline std::string to_string (float i) {
    return detail_string::stringexpr(i);
}
//! @overload 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);

Changes to cxxomfort/cxxomfort/impl/14-algorithm-equal.hpp.

3
4
5
6
7
8
9

10
11
12
13
14
15
16
..
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

#include <cxxomfort/base.hpp>
#include <type_traits>
#include "../algorithm.hpp"
// <algorithm> should have been included already

namespace cxxomfort {


//
// explicit sized ranges for equal, from C++14
//
namespace detail_algorithm {
template <typename T1, typename T2> struct heterogenous_equal_to {
    bool operator() (T1 const& t1, T2 const& t2) const { return t1 == t2; }
................................................................................
    return std::equal( ini1, fin1, ini2, c);
}


} //detail_algorithm

/**
 * @addtogroup cxx11-backports
 * @{
 */

//! Compare two sequences [ini1,fin1) and [ini2,fin2) for 
//! equality given comparator @p eq .
template <typename RangeIt1, typename RangeIt2, typename Compare> inline 
bool 
equal (RangeIt1 ini1, RangeIt1 fin1, RangeIt2 ini2, RangeIt2 fin2, Compare eq) {
    typedef typename std::iterator_traits<RangeIt1>::iterator_category cat_1;
    typedef typename std::iterator_traits<RangeIt2>::iterator_category cat_2;
    typedef std::random_access_iterator_tag rtag;
    using traits::is_same;
................................................................................
    typedef typename std::conditional< 
        (is_same<cat_1,rtag>::value and is_same<cat_2,rtag>::value)
        , traits::true_type, traits::false_type
    >::type dispatcher_t;
    return detail_algorithm::equal_impl(ini1,fin1,ini2,fin2,eq,dispatcher_t());
}

//! Compare two sequences for equality.
//! @overloads equal(ini1,fin1,ini2,fin2,eq)
template <typename RangeIt1, typename RangeIt2> inline 
bool 
equal (RangeIt1 ini1, RangeIt1 fin1, RangeIt2 ini2, RangeIt2 fin2) {
    typedef typename std::iterator_traits<RangeIt1>::value_type T1;
    typedef typename std::iterator_traits<RangeIt2>::value_type T2;
    detail_algorithm::heterogenous_equal_to< T1, T2 > this_eq;
    return detail_algorithm::equal_impl(ini1, fin1, ini2, fin2, this_eq);
}

//
// explicit sized ranges for mismatch, from C++14
//

//! Finds the first difference (dif1,dif2) between two
//! sequences [ini1,fin1) and [ini2,fin2), given comparator @p eq .


template<class InputIt1, class InputIt2, class BinaryPredicate>
std::pair<InputIt1, InputIt2>
mismatch (InputIt1 ini1, InputIt1 fin1, InputIt2 ini2, InputIt2 fin2, BinaryPredicate p) {
    while (ini1 != fin1 && ini2 != fin2 && p(*ini1, *ini2)) {
        ++ini1, ++ini2;
    }
    return std::make_pair(ini1, ini2);
}

//! Finds the first difference (dif1,dif2) between two sequences.
template<class InputIt1, class InputIt2>
std::pair<InputIt1, InputIt2>
mismatch (InputIt1 ini1, InputIt1 fin1, InputIt2 ini2, InputIt2 fin2) {
    typedef typename std::iterator_traits<InputIt1>::value_type T1;
    typedef typename std::iterator_traits<InputIt2>::value_type T2;
    detail_algorithm::heterogenous_equal_to< T1, T2 > this_eq;
    return mismatch(ini1, fin1, ini2, fin2, this_eq);
}

/**
 * @}
 */

} // cxxomfort

#endif







>







 







|
|
|
|
<
<







 







<
|













|
|
>
>









|









<
<
<
|



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

#include <cxxomfort/base.hpp>
#include <type_traits>
#include "../algorithm.hpp"
// <algorithm> should have been included already

namespace cxxomfort {
namespace algorithm {

//
// explicit sized ranges for equal, from C++14
//
namespace detail_algorithm {
template <typename T1, typename T2> struct heterogenous_equal_to {
    bool operator() (T1 const& t1, T2 const& t2) const { return t1 == t2; }
................................................................................
    return std::equal( ini1, fin1, ini2, c);
}


} //detail_algorithm

/**
 * @brief Compare two sequences [ini1,fin1) and [ini2,fin2) for equality given comparator @p eq . Four-iterators overload.
 * @ingroup cxx14-backports
 * @return a @c bool 
 */


template <typename RangeIt1, typename RangeIt2, typename Compare> inline 
bool 
equal (RangeIt1 ini1, RangeIt1 fin1, RangeIt2 ini2, RangeIt2 fin2, Compare eq) {
    typedef typename std::iterator_traits<RangeIt1>::iterator_category cat_1;
    typedef typename std::iterator_traits<RangeIt2>::iterator_category cat_2;
    typedef std::random_access_iterator_tag rtag;
    using traits::is_same;
................................................................................
    typedef typename std::conditional< 
        (is_same<cat_1,rtag>::value and is_same<cat_2,rtag>::value)
        , traits::true_type, traits::false_type
    >::type dispatcher_t;
    return detail_algorithm::equal_impl(ini1,fin1,ini2,fin2,eq,dispatcher_t());
}


//! @overload equal(ini1,fin1,ini2,fin2,eq)
template <typename RangeIt1, typename RangeIt2> inline 
bool 
equal (RangeIt1 ini1, RangeIt1 fin1, RangeIt2 ini2, RangeIt2 fin2) {
    typedef typename std::iterator_traits<RangeIt1>::value_type T1;
    typedef typename std::iterator_traits<RangeIt2>::value_type T2;
    detail_algorithm::heterogenous_equal_to< T1, T2 > this_eq;
    return detail_algorithm::equal_impl(ini1, fin1, ini2, fin2, this_eq);
}

//
// explicit sized ranges for mismatch, from C++14
//

/**
 * @brief Finds the first difference (dif1,dif2) between two sequences [ini1,fin1) and [ini2,fin2), given comparator @p eq . Four-iterator overload.
 * @ingroup cxx14-backports
 */
template<class InputIt1, class InputIt2, class BinaryPredicate>
std::pair<InputIt1, InputIt2>
mismatch (InputIt1 ini1, InputIt1 fin1, InputIt2 ini2, InputIt2 fin2, BinaryPredicate p) {
    while (ini1 != fin1 && ini2 != fin2 && p(*ini1, *ini2)) {
        ++ini1, ++ini2;
    }
    return std::make_pair(ini1, ini2);
}

//! @overload mismatch
template<class InputIt1, class InputIt2>
std::pair<InputIt1, InputIt2>
mismatch (InputIt1 ini1, InputIt1 fin1, InputIt2 ini2, InputIt2 fin2) {
    typedef typename std::iterator_traits<InputIt1>::value_type T1;
    typedef typename std::iterator_traits<InputIt2>::value_type T2;
    detail_algorithm::heterogenous_equal_to< T1, T2 > this_eq;
    return mismatch(ini1, fin1, ini2, fin2, this_eq);
}




}
} // cxxomfort

#endif

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

1
2
3
4
5

6
7
8
9
10
11
12
..
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
..
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
...
165
166
167
168
169
170
171



172
173
174
175
176

177
178
179
180
181
182
183
...
189
190
191
192
193
194
195

196

197

198

199

200
201
202
203
204
205
206

207
208
209
#ifndef CXXOMFORT_IMPL_FUNCTIONAL_14FUNCTORS_HPP
#define CXXOMFORT_IMPL_FUNCTIONAL_14FUNCTORS_HPP
/**
 * @file impl/14-functors.hpp
 * @brief Partial implementation of N3421 "Easier <functional> syntax" aka: Transparent Functors

 * 
 * @see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3421.htm
 * @see http://stackoverflow.com/questions/17737132/transparent-operator-functors
 * 
 * This header should be included @b after <functional> has been included.
 * 
 * Interfaces exported in this header:
................................................................................
#include "../type_traits.hpp"
#include "../util/traits_ct.hpp"

namespace cxxomfort {
namespace functional {

/**
 * @addtogroup functional
 * @{
 */
template <typename T = void> struct less 
: std::less<T> {};
template <typename T = void> struct greater 
: std::greater<T> {};
template <typename T = void> struct less_equal 
................................................................................
: std::less_equal<T> {};
template <typename T = void> struct greater_equal 
: std::greater_equal<T> {};
template <typename T = void> struct equal_to 
: std::equal_to<T> {};
template <typename T = void> struct not_equal_to 
: std::not_equal_to<T> {};





#define LPP_SPEC_FUNCTIONAL_VOID(Op,Sym) \
/**   \
 * @brief Transparent functor for '@c Op ', to be used as <code>Op<void></code>. \
 *  \
 * These operators permit transparent (not type-dependent) comparators \
 * to be used in the contexts where eg.: <code>std::less</code> is expected. \
 *  \
 * @ref cxx03-backports   \
 * @ref cxx11-backports   \
 */   \
template <> struct Op <void> :  \
std::Op <int> { \
    typedef bool result_type; \
    template <typename T, typename U> \
    inline bool operator() (T const& t, U const& u) const { return t Sym u; } \
}; \
................................................................................
: std::bit_xor<T> {};
// this was missing from the original STL
template <typename T = void> struct bit_not {
    typedef T result_type;
    typedef T argument_type;
    inline T operator() (T const& t) const { return ~t; }
};






template <typename T = void> struct plus 
: std::plus<T> {};
template <typename T = void> struct minus 
: std::minus<T> {};
template <typename T = void> struct multiplies 
: std::multiplies<T> {};
template <typename T = void> struct divides 
: std::divides<T> {};
template <typename T = void> struct modulus 
: std::modulus<T> {};





#if (CXXOMFORT_CXX_STD < 2011)

// Under C++03, one can not trust that std::common_type is available 
// (because no decltype), so we assume that heterogeneous functors 
// return homogeneously to the left (aka: they return the type of 1st operand).

................................................................................
/**
 * @}
 */

} //cxxomfort::extras
} //cxxomfort




/*
 * Transparent functors were established in C++14
 */
#if (CXXOMFORT_CXX_STD < 2014)
namespace std {

    //! Transparent @em equal_to functor.
    template<> struct equal_to<void>  : ::cxxomfort::functional::equal_to<void> {}; ///< transparent specialization for @c std::equal_to
    //! Transparent @em not_equal_to functor.
    template<> struct not_equal_to<void>  : ::cxxomfort::functional::not_equal_to<void> {};
    //! Transparent @em less functor.
    template<> struct less<void>      : ::cxxomfort::functional::less<void> {};
    //! Transparent @em greater functor.
................................................................................
    //! Transparent @em bit_or functor.
    template<> struct bit_or<void>    : ::cxxomfort::functional::bit_or<void> {};
    //! Transparent @em bit_and functor.
    template<> struct bit_and<void>   : ::cxxomfort::functional::bit_and<void> {};
    //! Transparent @em bit_xor functor.
    template<> struct bit_xor<void>   : ::cxxomfort::functional::bit_xor<void> {};


    template<> struct plus<void>   : ::cxxomfort::functional::plus<void> {};

    template<> struct minus<void>   : ::cxxomfort::functional::minus<void> {};

    template<> struct multiplies<void>   : ::cxxomfort::functional::multiplies<void> {};

    template<> struct divides<void>   : ::cxxomfort::functional::divides<void> {};

    template<> struct modulus<void>   : ::cxxomfort::functional::modulus<void> {};


    
    
}
#endif // c++14


#endif // CXXOMFORT_EXTRAS_14FUNCTORS_HPP




|
|
>







 







|







 







>
>
>
>








|
|







 







>
>
>
>
>












>
>
>







 







>
>
>





>







 







>
|
>
|
>
|
>
|
>
|
|
|
<
<
<
|
>
|
|
<
1
2
3
4
5
6
7
8
9
10
11
12
13
..
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
..
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
...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224



225
226
227
228

#ifndef CXXOMFORT_IMPL_FUNCTIONAL_14FUNCTORS_HPP
#define CXXOMFORT_IMPL_FUNCTIONAL_14FUNCTORS_HPP
/**
 * @file
 * @brief Partial implementation of N3421 "Easier <functional> syntax" aka: Transparent Functors
 * @ingroup cxx14-backports
 * 
 * @see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3421.htm
 * @see http://stackoverflow.com/questions/17737132/transparent-operator-functors
 * 
 * This header should be included @b after <functional> has been included.
 * 
 * Interfaces exported in this header:
................................................................................
#include "../type_traits.hpp"
#include "../util/traits_ct.hpp"

namespace cxxomfort {
namespace functional {

/**
 * @ingroup cxx14-backports
 * @{
 */
template <typename T = void> struct less 
: std::less<T> {};
template <typename T = void> struct greater 
: std::greater<T> {};
template <typename T = void> struct less_equal 
................................................................................
: std::less_equal<T> {};
template <typename T = void> struct greater_equal 
: std::greater_equal<T> {};
template <typename T = void> struct equal_to 
: std::equal_to<T> {};
template <typename T = void> struct not_equal_to 
: std::not_equal_to<T> {};

/**
 * @}
 */

#define LPP_SPEC_FUNCTIONAL_VOID(Op,Sym) \
/**   \
 * @brief Transparent functor for '@c Op ', to be used as <code>Op<void></code>. \
 *  \
 * These operators permit transparent (not type-dependent) comparators \
 * to be used in the contexts where eg.: <code>std::less</code> is expected. \
 *  \
 * @ingroup cxx14-backports   \
 * @sa 3421 \
 */   \
template <> struct Op <void> :  \
std::Op <int> { \
    typedef bool result_type; \
    template <typename T, typename U> \
    inline bool operator() (T const& t, U const& u) const { return t Sym u; } \
}; \
................................................................................
: std::bit_xor<T> {};
// this was missing from the original STL
template <typename T = void> struct bit_not {
    typedef T result_type;
    typedef T argument_type;
    inline T operator() (T const& t) const { return ~t; }
};

/**
 * @ingroup cxx14-backports
 * @{
 */

template <typename T = void> struct plus 
: std::plus<T> {};
template <typename T = void> struct minus 
: std::minus<T> {};
template <typename T = void> struct multiplies 
: std::multiplies<T> {};
template <typename T = void> struct divides 
: std::divides<T> {};
template <typename T = void> struct modulus 
: std::modulus<T> {};

/**
 * @}
 */

#if (CXXOMFORT_CXX_STD < 2011)

// Under C++03, one can not trust that std::common_type is available 
// (because no decltype), so we assume that heterogeneous functors 
// return homogeneously to the left (aka: they return the type of 1st operand).

................................................................................
/**
 * @}
 */

} //cxxomfort::extras
} //cxxomfort

// for the facilities to function correctly they are rebuilt in 
// namespace std; but we give users the option not to.
#if (!defined(CXXOMFORT_NO_STD_USING))
/*
 * Transparent functors were established in C++14
 */
#if (CXXOMFORT_CXX_STD < 2014)
namespace std {

    //! Transparent @em equal_to functor.
    template<> struct equal_to<void>  : ::cxxomfort::functional::equal_to<void> {}; ///< transparent specialization for @c std::equal_to
    //! Transparent @em not_equal_to functor.
    template<> struct not_equal_to<void>  : ::cxxomfort::functional::not_equal_to<void> {};
    //! Transparent @em less functor.
    template<> struct less<void>      : ::cxxomfort::functional::less<void> {};
    //! Transparent @em greater functor.
................................................................................
    //! Transparent @em bit_or functor.
    template<> struct bit_or<void>    : ::cxxomfort::functional::bit_or<void> {};
    //! Transparent @em bit_and functor.
    template<> struct bit_and<void>   : ::cxxomfort::functional::bit_and<void> {};
    //! Transparent @em bit_xor functor.
    template<> struct bit_xor<void>   : ::cxxomfort::functional::bit_xor<void> {};

    //! Transparent @em plus functor.
    template<> struct plus<void>   : ::cxxomfort::functional::plus<void> {}; ///< transparent specialization for @c std::plus
    //! Transparent @em minus functor.
    template<> struct minus<void>   : ::cxxomfort::functional::minus<void> {};
    //! Transparent @em multiplies functor.
    template<> struct multiplies<void>   : ::cxxomfort::functional::multiplies<void> {};
    //! Transparent @em divides functor.
    template<> struct divides<void>   : ::cxxomfort::functional::divides<void> {};
    //! Transparent @em modulus functor.
    template<> struct modulus<void>   : ::cxxomfort::functional::modulus<void> {};

}



#endif // c++14
#endif // no std

#endif // CXXOMFORT_EXTRAS_14FUNCTORS_HPP

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

9
10
11
12
13
14
15

16
17
18
19
20
21
22
..
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
// 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 {


/**
 * @ingroup utility
 * @{
 */
template <typename T, T... Elems>
struct integer_sequence {
................................................................................

#endif

/**
 * @}
 */


} // cxxomfort::

#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {

    using cxxomfort::integer_sequence;
    using cxxomfort::index_sequence;
    using cxxomfort::make_integer_sequence;
    using cxxomfort::make_index_sequence;

} // namespace std
#endif // std using

#endif // c++11

#endif // support
#endif









>







 







>




>
|
|
|
|
<









9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
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
// 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 {
namespace utility {

/**
 * @ingroup utility
 * @{
 */
template <typename T, T... Elems>
struct integer_sequence {
................................................................................

#endif

/**
 * @}
 */

} // utility::
} // cxxomfort::

#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {
    //! Brings @c integer_sequence to std.
    using cxxomfort::utility::integer_sequence;
    using cxxomfort::utility::index_sequence;
    using cxxomfort::utility::make_integer_sequence;
    using cxxomfort::utility::make_index_sequence;

} // namespace std
#endif // std using

#endif // c++11

#endif // support
#endif


Added cxxomfort/cxxomfort/impl/14-make_unique.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
#ifndef CXXOMFORT_UTIL_MAKE_UNIQUE_HPP
#define CXXOMFORT_UTIL_MAKE_UNIQUE_HPP

#include "../base.hpp"
#include "../impl/unique_ptr.hpp"

// this is included after unique_ptr

// Add make_unique
// equivalent to return std::unique_ptr<T>(new T(std::forward<Args>(args)...));

namespace std {

#if (CXXOMFORT_CXX_STD == 2011)

template <typename T, typename ...Args> inline
unique_ptr<T> make_unique (Args&&... args) {
    return std::unique_ptr<T>( new T(std::forward<Args>(args)... ) );
}

#elif (CXXOMFORT_CXX_STD < 2011)
template <typename T> inline
unique_ptr<T> make_unique () {
    return unique_ptr<T> (new T());
}
template <typename T, typename A1> inline
unique_ptr<T> make_unique (CXXO_FWD_REF(A1) a1) {
    return unique_ptr<T> (new T( std::forward<A1>(a1) ));
}
template <typename T, typename A1, typename A2> inline
unique_ptr<T> make_unique (CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2) {
    return unique_ptr<T> (new T( std::forward<A1>(a1), std::forward<A2>(a2) ));
}
template <typename T, typename A1, typename A2, typename A3> inline
unique_ptr<T> make_unique (CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2, CXXO_FWD_REF(A3) a3) {
    return unique_ptr<T> (new T( 
       std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3) ));
}
template <typename T, typename A1, typename A2, typename A3, typename A4> inline
unique_ptr<T> make_unique (CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2, CXXO_FWD_REF(A3) a3, CXXO_FWD_REF(A4) a4) {
    return unique_ptr<T> (new T(
       std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3)
     , std::forward<A4>(a4) ));
}
template <typename T, typename A1, typename A2, typename A3, typename A4, typename A5> inline
unique_ptr<T> make_unique (CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2, CXXO_FWD_REF(A3) a3, CXXO_FWD_REF(A4) a4, CXXO_FWD_REF(A5) a5) {
    return unique_ptr<T> (new T(
      std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), 
      std::forward<A4>(a4), std::forward<A5>(a5) ));
}

#endif
}

#endif

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

1
2




3
4
5
6
7
8
9
..
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
...
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
...
201
202
203
204
205
206
207
208
209

210
















211
212
213
#ifndef CXXOMFORT_IMPL_TUPLEGETTYPE_HPP
#define CXXOMFORT_IMPL_TUPLEGETTYPE_HPP




/*
 * Support for getting elements of a tuple by type
 * (C++14 proposal n3584 "Wording for Addressing Tuples by Type")
 * based off of n3404 and n3584
 * http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3584.html
 * 
 * Interfaces defined in this header:
................................................................................
#if (defined(CXXOMFORT_NOTICES))
    #if (CXXOMFORT_NOTICES > 1)
    #pragma message CXXO_NOTICE("enabled tuple get<type> implementation")
    #endif
#endif


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

namespace cxxomfort {
namespace tuple {
namespace detail {

/*
 * Check if an element of type T is already in Tuple, 
 * if so, returns its index (0...N-1)
................................................................................
namespace std {
#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);
................................................................................

// bring the new names to namespace std
namespace std {
    //using ::cxxomfort::tuple::get;
    using ::cxxomfort::tuple::tuple_index;
}

//#undef CXXO_TI_STRI0(x)
//#undef CXXO_TI_STRI(x)


















#endif // CXXOMFORT_EXTRAS_LOCALFN_HPP




>
>
>
>







 







<
<
<







 







>
>
>
>








>








>










|









>







 







|
|
>

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


1
2
3
4
5
6
7
8
9
10
11
12
13
..
26
27
28
29
30
31
32



33
34
35
36
37
38
39
...
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
...
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
#ifndef CXXOMFORT_IMPL_TUPLEGETTYPE_HPP
#define CXXOMFORT_IMPL_TUPLEGETTYPE_HPP
/**
 * @file
 */

/*
 * Support for getting elements of a tuple by type
 * (C++14 proposal n3584 "Wording for Addressing Tuples by Type")
 * based off of n3404 and n3584
 * http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3584.html
 * 
 * Interfaces defined in this header:
................................................................................
#if (defined(CXXOMFORT_NOTICES))
    #if (CXXOMFORT_NOTICES > 1)
    #pragma message CXXO_NOTICE("enabled tuple get<type> implementation")
    #endif
#endif





namespace cxxomfort {
namespace tuple {
namespace detail {

/*
 * Check if an element of type T is already in Tuple, 
 * if so, returns its index (0...N-1)
................................................................................
namespace std {
#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

/**
 * @brief Return a member of a tuple given its type as a template argument.
 * @ingroup cxx14-backports
 */
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));
}

//! @overload get
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));
}

//! @overload get
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
//! Return a member from a tuple given its type.
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);
}

//! @overload get
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);
................................................................................

// bring the new names to namespace std
namespace std {
    //using ::cxxomfort::tuple::get;
    using ::cxxomfort::tuple::tuple_index;
}

#if defined(DOXYGEN_DOC)
namespace cxxomfort {
namespace tuple {

/**
 * @brief Return a member of a tuple given its type as a template argument.
 * @ingroup cxx14-backports
 * @tparam T a type, such that it exists in the type pack @c TupleArgs... .
 */
template <typename T, typename... TupleArgs>
T& get (std::tuple<TupleArgs...>&) {}

//! @overload get
template <typename T, typename... TupleArgs>
T const& get (std::tuple<TupleArgs...> const&) {}

}
}
#endif

#endif // 


Changes to cxxomfort/cxxomfort/impl/17-as_const.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
#ifndef CXXOMFORT_IMPL_AS_CONST_HPP
#define CXXOMFORT_IMPL_AS_CONST_HPP
/**
 * @file impl/17-as_const.hpp
 * @brief Implements "as_const" proposal.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 */

// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4380.html

#define CXXOMFORT_IMPLEMENTS_n4380 1

#include "../config.hpp"


#include <utility>
#include <type_traits>
#include <cxxomfort/using.hpp>

// would go in <utility>
// works with l-values only

namespace cxxomfort {


/**

 * @ingroup utility
 * @ref cxx03-backports
 * @ref cxx11-backports
 * @ref cxx14-backports
 * @{
 */

//! returns a @c const  view of object @p t .
template< typename T >
inline CXXO_CONSTEXPR typename std::add_const< T >::type & 
as_const( T &t ) CXXO_NOEXCEPT {
    return t;
}

/**
 * @}
 */









} // cxxomfort






#endif // file



|










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






|
|
<
|
>
>
>
>
>
>
>
>
|
>
>
|
|
>
>
|
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
#ifndef CXXOMFORT_IMPL_AS_CONST_HPP
#define CXXOMFORT_IMPL_AS_CONST_HPP
/**
 * @file
 * @brief Implements "as_const" proposal.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 */

// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4380.html

#define CXXOMFORT_IMPLEMENTS_n4380 1

#include "../config.hpp"
#include "../type_traits.hpp"
#include "../using.hpp"
#include <utility>
#include <type_traits>





namespace cxxomfort {
namespace utility {

/**
 * @brief returns a @c const  view of object @p t . A @ref cxx17-backports .
 * @ingroup utility
 * @return A reference to its argument with @c const added.
 * @sa cxx17-backports


 */


template< typename T >
inline CXXO_CONSTEXPR typename std::add_const< T >::type & 
as_const( T &t ) CXXO_NOEXCEPT {
    return t;
}

} // utility
} // cxxomfort



#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {
    using cxxomfort::utility::as_const;
}
#endif

#if defined (DOXYGEN_DOC)
namespace cxxomfort {
    //! @brief Const view
    template <typename T> T const& as_const (T&) {}
}

#endif

#endif // file

Changes to cxxomfort/cxxomfort/impl/17-byte.hpp.

1
2




3
4
5
6
7
8
9
..
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
..
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


#ifndef CXXOMFORT_IMPL_CSTDDEF_BYTE_HPP
#define CXXOMFORT_IMPL_CSTDDEF_BYTE_HPP





/**
 * 
 * 
 * byte accepts the follosing operations:
 * 
 * * to_byte (Integral) -> byte
................................................................................
// -----

#if (defined(CXXOMFORT_USING_stdbyte))

#include "../library/typesafe_enum.hpp"

namespace cxxomfort {
namespace stdbyte {
    


struct mybyte_def { /* typedef unsigned char type; */ enum type {}; };
typedef typesafe_enum<mybyte_def,unsigned char> byteimpl;
// quick and easy encapsulation

struct byte: private byteimpl  {
    byte (byte const& b) : byteimpl((byteimpl const&)b) {}
    explicit byte (unsigned char c) : byteimpl( from_underlying<byteimpl>(c) ) {}


/*
    byte (unsigned char c) : byteimpl(c) {}
    byte (signed char c) : byteimpl(static_cast<unsigned char>(c)) {}
    byte (char c) : byteimpl(static_cast<unsigned char>(c)) {}























*/








    using byteimpl::byteimpl;
    using byteimpl::underlying;
    using byteimpl::operator=;
    using byteimpl::equals;

/*
    byte& operator= (byte const& b) CXXO_NOEXCEPT {
        (unsigned char&)(*this)= b.underlying();
        return *this;
    }

*/

    byte& operator&= (byte const& b) CXXO_NOEXCEPT {
        (unsigned char&)(*this)&= b.underlying();
        return *this;
    }

    byte& operator|= (byte const& b) CXXO_NOEXCEPT {
        (unsigned char&)(*this)|= b.underlying();
................................................................................

    friend bool operator== (byte, byte) CXXO_NOEXCEPT;

    template <typename T>
    friend T to_integer (byte) CXXO_NOEXCEPT;

    private:
    typedef byteimpl this_base;
};








byte operator& (byte b1, byte b2) CXXO_NOEXCEPT {

    return byte (b1&= b2);
}


byte operator| (byte b1, byte b2) CXXO_NOEXCEPT {
    return byte (b1|= b2);
}


byte operator^ (byte b1, byte b2) CXXO_NOEXCEPT {
    return byte (b1^= b2);
}

inline bool operator== (byte b1, byte b2) CXXO_NOEXCEPT {
    return b1.underlying()==b2.underlying();
}

inline bool operator!= (byte const& b1, byte const& b2) CXXO_NOEXCEPT {
    return !(b1==b2);
}


template <typename TI CXXOMFORT_CXX11_CODE(=int,) >
TI to_integer (byte b) CXXO_NOEXCEPT {
    static_assert (std::is_integral<TI>::value, "is_integral");
    return static_cast<TI>(b.underlying());
}

template <typename TI> 
byte to_byte (TI i) {

    static_assert (std::is_integral<TI>::value, "is_integral");
    return byte( static_cast<unsigned char>(i) );
}

template <typename Stream>
Stream& operator<< (Stream& os, byte const& b) CXXO_NOEXCEPT {
    os<< to_integer<unsigned char>(b);
    return os;
}





// stdbyte


}
// cxxomfort
}

#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {

    using namespace cxxomfort::stdbyte;


}
#endif

#endif // stdbyte






#endif




>
>
>
>







 







|
|
>
>
|



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

<





<
<







 







|

>

>
>
>
>

>
|
>



>
|



>
|












|







>










>
>
>

<
>
>






>
|
>
>





>
>
>
>
>

>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
..
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
...
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
#ifndef CXXOMFORT_IMPL_CSTDDEF_BYTE_HPP
#define CXXOMFORT_IMPL_CSTDDEF_BYTE_HPP
/**
 * @file 17-byte.hpp
 * @brief Header file for implementation of std::byte backport.
 */

/**
 * 
 * 
 * byte accepts the follosing operations:
 * 
 * * to_byte (Integral) -> byte
................................................................................
// -----

#if (defined(CXXOMFORT_USING_stdbyte))

#include "../library/typesafe_enum.hpp"

namespace cxxomfort {
namespace cstddef {

namespace detail { // detail

struct mybyte_def { enum type {};  };
typedef typesafe_enum<mybyte_def,unsigned char> byteimpl;
// quick and easy encapsulation




}

/**

 * @brief "byte" type for C++17.
 * @ingroup cxx17-backports
 * @ref cstddef
 * 
 * A '<code>byte</code>' is much like an <code>unsigned char</code>, 
 * except that it is not an integral type but a compound-like 
 * type of its own. 
 * 
 * Only bit operations (via bitmask operators) and explicit integral 
 * transformations are defined for it.
 * 
 * The following basic operations are allowed:
 * 
 * @code
 * byte b = to_byte(0xnn);
 * byte c = from_underlying<byte>(0xnn)
 * b | c;
 * b & c;
 * b ^ c;
 * b >>= 2;
 * c <<= 3;
 * c= ~b;
 * int cint = to_integer<int>(c);
 * @endcode
 *
 */
struct byte: protected detail::byteimpl  {
    private:
    typedef detail::byteimpl underlying_t;
    public:
    
    byte (byte const& b) : detail::byteimpl((detail::byteimpl const&)b) {}
    explicit byte (unsigned char c) : detail::byteimpl( from_underlying<detail::byteimpl>(c) ) {}

    //using byteimpl::byteimpl;
    using detail::byteimpl::underlying;
    //using detail::byteimpl::operator=;
    using detail::byteimpl::equals;


    byte& operator= (byte const& b) CXXO_NOEXCEPT {
        (unsigned char&)(*this)= b.underlying();
        return *this;
    }



    byte& operator&= (byte const& b) CXXO_NOEXCEPT {
        (unsigned char&)(*this)&= b.underlying();
        return *this;
    }

    byte& operator|= (byte const& b) CXXO_NOEXCEPT {
        (unsigned char&)(*this)|= b.underlying();
................................................................................

    friend bool operator== (byte, byte) CXXO_NOEXCEPT;

    template <typename T>
    friend T to_integer (byte) CXXO_NOEXCEPT;

    private:
    typedef detail::byteimpl this_base;
};
static_assert (sizeof(byte)==sizeof(char), "Implementation failure: byte needs to have the same sizeof as char!");

/**
 * @ingroup cxx17-backports
 * @{
 */

//! @brief AND (&) of two @c byte s.
static inline byte operator& (byte b1, byte b2) CXXO_NOEXCEPT {
    //static_assert (sizeof(byte)==1, "sizeof(byte)==1");
    return byte (b1&= b2);
}

//! @brief OR (|) of two @c byte s.
static inline byte operator| (byte b1, byte b2) CXXO_NOEXCEPT {
    return byte (b1|= b2);
}

//! @brief XOR (^) of two @c byte s.
static inline byte operator^ (byte b1, byte b2) CXXO_NOEXCEPT {
    return byte (b1^= b2);
}

inline bool operator== (byte b1, byte b2) CXXO_NOEXCEPT {
    return b1.underlying()==b2.underlying();
}

inline bool operator!= (byte const& b1, byte const& b2) CXXO_NOEXCEPT {
    return !(b1==b2);
}


template <typename TI >
TI to_integer (byte b) CXXO_NOEXCEPT {
    static_assert (std::is_integral<TI>::value, "is_integral");
    return static_cast<TI>(b.underlying());
}

template <typename TI> 
byte to_byte (TI i) {
    static_assert (sizeof(byte)==sizeof(char), "byte does not seem to be a char");
    static_assert (std::is_integral<TI>::value, "is_integral");
    return byte( static_cast<unsigned char>(i) );
}

template <typename Stream>
Stream& operator<< (Stream& os, byte const& b) CXXO_NOEXCEPT {
    os<< to_integer<unsigned char>(b);
    return os;
}

/**
 * @}
 */



// cstddef
}
// cxxomfort
}

#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {
    //! @ref cxx17-backports
    using cxxomfort::cstddef::byte;
    using cxxomfort::cstddef::to_byte;
    using cxxomfort::cstddef::to_integer;
}
#endif

#endif // stdbyte

#if (defined(DOXYGEN_DOC))
namespace std {
    //! byte object representation
    struct byte {};
}
#endif

#endif

Changes to cxxomfort/cxxomfort/impl/17-clamp.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
#ifndef CXXOMFORT_IMPL_CLAMP_HPP
#define CXXOMFORT_IMPL_CLAMP_HPP
/**
 * @file impl/17-clamp.hpp
 * @brief Header file providing implementation of C++17's "clamp" algorithm.
 * @sa http://en.cppreference.com/w/cpp/algorithm/clamp
 * 
 */

#if (CXXOMFORT_CXX_STD < 2017)

namespace cxxomfort {
namespace algorithm {

/**
 * @brief Clamps a value.
 * @ingroup algorithm
 * @ref cxx03-backports
 * @ref cxx11-backports
 * @ref cxx14-backports
 */
template<class T, class Compare>
CXXO_CONSTEXPR
T const& clamp ( T const& val, T const& lo, T const& hi, Compare comp) {
    return assert( !comp(hi, lo) ),
        comp(val, lo) ? lo : comp(hi, val) ? hi : val;
}

//! @overloads clamp
template<class T>
CXXO_CONSTEXPR
T const& clamp ( T const& val, T const& lo, T const& hi) {
    return clamp (val, lo, hi, std::less<T>() );
}

} // algorithm
} // cxxomfort


namespace std {
    using ::cxxomfort::algorithm::clamp;
}



#endif // c++17

#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
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
#ifndef CXXOMFORT_IMPL_CLAMP_HPP
#define CXXOMFORT_IMPL_CLAMP_HPP
/**
 * @file
 * @brief Header file providing implementation of C++17's "clamp" algorithm.
 * @sa http://en.cppreference.com/w/cpp/algorithm/clamp
 * 
 */

#if (CXXOMFORT_CXX_STD < 2017)

namespace cxxomfort {
namespace algorithm {

/**
 * @brief Clamps a value.
 * @ingroup cxx17-backports
 * @ref algorithm


 */
template<class T, class Compare>
CXXO_CONSTEXPR
T const& clamp ( T const& val, T const& lo, T const& hi, Compare comp) {
    return assert( !comp(hi, lo) ),
        comp(val, lo) ? lo : comp(hi, val) ? hi : val;
}

//! @overload clamp
template<class T>
CXXO_CONSTEXPR
T const& clamp ( T const& val, T const& lo, T const& hi) {
    return clamp (val, lo, hi, std::less<T>() );
}

} // algorithm
} // cxxomfort

#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {
    using cxxomfort::algorithm::clamp;
}

#endif

#endif // c++17

#endif

Changes to cxxomfort/cxxomfort/impl/17-make_from_tuple.hpp.

1
2
3
4

5
6
7
8
9
10
11
..
84
85
86
87
88
89
90










91



92


#ifndef CXXOMFORT_IMPL_MAKE_FROM_TUPLE_HPP
#define CXXOMFORT_IMPL_MAKE_FROM_TUPLE_HPP
/*
 * 

 */

#include <cxxomfort/base.hpp>
#include <cxxomfort/tuple.hpp> // index_sequence
#include <tuple> // ...duh

namespace cxxomfort {
................................................................................
namespace std {
    using cxxomfort::tuple::make_from_tuple;
}
#endif
#endif
















#endif




|
|
>







 







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

>
>
1
2
3
4
5
6
7
8
9
10
11
12
..
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#ifndef CXXOMFORT_IMPL_MAKE_FROM_TUPLE_HPP
#define CXXOMFORT_IMPL_MAKE_FROM_TUPLE_HPP
/**
 * @file
 * @brief Implementation header for C++17's make_from_tuple
 */

#include <cxxomfort/base.hpp>
#include <cxxomfort/tuple.hpp> // index_sequence
#include <tuple> // ...duh

namespace cxxomfort {
................................................................................
namespace std {
    using cxxomfort::tuple::make_from_tuple;
}
#endif
#endif


#if defined(DOXYGN_DOC)
namespace cxxomfort {
namespace tuple {
    /**
     * @brief Create an object from a tuple expression
     * @ingroup cxx17-backports
     * @return An object, constructed via a constructor call using a tuple as arguments.
     */
    template <typename T, typename... TupleArgs>
    T make_from_tuple (std::tuple<TupleArgs...> const& Tuple) {}
    
}
}

#endif

#endif

Changes to cxxomfort/cxxomfort/impl/17-tuple_apply.hpp.

1
2




3
4
5
6
7
8
9
..
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
...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
...
261
262
263
264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
#ifndef CXXOMFORT_IMPL_TUPLEAPPLY_HPP
#define CXXOMFORT_IMPL_TUPLEAPPLY_HPP




/*
 * Support for applying a tuple as arguments to a function
 * (C++14 proposals n3829 and n3915)
 * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3829.pdf
 * 
 * Interfaces defined in this header:
 * 
................................................................................

//
// tuple_apply
// (call a function using an unpacked tuple as arguments)
//

#if (CXXOMFORT_CXX_STD >= 2011) || \
    (CXXOMFORT_CXX_EMULATION == 2011 && CXXO_EMULATION_rvref && CXXO_EMULATION_variadic)

// http://stackoverflow.com/questions/687490/how-do-i-expand-a-tuple-into-variadic-template-functions-arguments/12650100#12650100

//
// tuple unpack
// (solution presented in n3658 "Integer Sequences")
//

template<typename F, typename Tuple, size_t... I>
  auto
  apply_(F&& f, Tuple&& args, std::index_sequence<I...>)
  -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...))
  {
    return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...);
  }












template<typename F, typename Tuple,
    typename Dec= typename std::decay<Tuple>::type, 
    typename Indices = std::make_index_sequence<std::tuple_size<Dec>::value>>
  auto
  apply(F&& f, Tuple&& args)
  -> decltype(apply_(std::forward<F>(f), std::forward<Tuple>(args), Indices()))
................................................................................
    , typename A3, typename A4, typename A5> 
struct FnReturnType<R(A0,A1,A2,A3,A4,A5,...)> 
: FnReturnType<R(A0)> {};
template <typename R, typename A0, typename A1, typename A2
    , typename A3, typename A4, typename A5> 
struct FnReturnType<R(*)(A0,A1,A2,A3,A4,A5,...)> 
: FnReturnType<R(A0)> {};



template <typename F, typename Tuple, unsigned int S= std::tuple_size< typename std::remove_cv<Tuple>::type>::value> 
struct call_impl {
};

#define GET_(x) get<x>(t)
................................................................................
#undef GET_

template <typename F, typename Tuple>
typename FnReturnType<F>::type
apply (F f, Tuple& t) {
    //typedef typename FnReturnType< typename std::remove_pointer<F>::type >::type ret_type;
    typedef typename FnReturnType<F>::type R;
    //std::cerr<< "[call (Tuple const&) [return_type= "<< cxxomfort::typeid_demangle(typeid(ret_type))<< "] ]"<< std::endl;
    //std::cerr<< "[call (Tuple const&) [Tuple="<< cxxomfort::typeid_demangle(typeid(Tuple))<< "] ]"<< std::endl;
    return call_impl<F,Tuple>::template call<R>( f, t );
}

template <typename F, typename Tuple>
typename FnReturnType<F>::type
apply (F f, Tuple const& t) {
    typedef typename FnReturnType<F>::type R;
................................................................................
Tuple& apply (F f, Tuple& t) {
    tuple_apply_t<F,Tuple>(f,t);
    return t;
}
#endif




} //detail_tuple::
}


namespace std {
    using cxxomfort::tuple::apply;
}



#endif


>
>
>
>







 







|







>







>
>
>
>
>
>
>
>
>
>
>







 







<







 







<
<







 







<
<



>



|



1
2
3
4
5
6
7
8
9
10
11
12
13
..
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
...
124
125
126
127
128
129
130

131
132
133
134
135
136
137
...
216
217
218
219
220
221
222


223
224
225
226
227
228
229
...
274
275
276
277
278
279
280


281
282
283
284
285
286
287
288
289
290
291
#ifndef CXXOMFORT_IMPL_TUPLEAPPLY_HPP
#define CXXOMFORT_IMPL_TUPLEAPPLY_HPP
/**
 * @file
 */

/*
 * Support for applying a tuple as arguments to a function
 * (C++14 proposals n3829 and n3915)
 * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3829.pdf
 * 
 * Interfaces defined in this header:
 * 
................................................................................

//
// tuple_apply
// (call a function using an unpacked tuple as arguments)
//

#if (CXXOMFORT_CXX_STD >= 2011) || \
    (CXXOMFORT_CXX_EMULATION == 2011 && CXXO_COMPILER_SUPPORT_rvref && CXXO_COMPILER_SUPPORT_variadic && CXXO_COMPILER_SUPPORT_trailing_returns ) 

// http://stackoverflow.com/questions/687490/how-do-i-expand-a-tuple-into-variadic-template-functions-arguments/12650100#12650100

//
// tuple unpack
// (solution presented in n3658 "Integer Sequences")
//

template<typename F, typename Tuple, size_t... I>
  auto
  apply_(F&& f, Tuple&& args, std::index_sequence<I...>)
  -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...))
  {
    return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...);
  }

/**
 * @brief Applies a tuple as an argument pack to a function.
 * @ingroup tuple
 * @return The return type from the function @a f .
 * 
 * Given the function @a f and the tuple @a args , 
 * @c apply  performs the function call 
 * <code>f (args[0], args[1], ...)</code>.
 * 
 */

template<typename F, typename Tuple,
    typename Dec= typename std::decay<Tuple>::type, 
    typename Indices = std::make_index_sequence<std::tuple_size<Dec>::value>>
  auto
  apply(F&& f, Tuple&& args)
  -> decltype(apply_(std::forward<F>(f), std::forward<Tuple>(args), Indices()))
................................................................................
    , typename A3, typename A4, typename A5> 
struct FnReturnType<R(A0,A1,A2,A3,A4,A5,...)> 
: FnReturnType<R(A0)> {};
template <typename R, typename A0, typename A1, typename A2
    , typename A3, typename A4, typename A5> 
struct FnReturnType<R(*)(A0,A1,A2,A3,A4,A5,...)> 
: FnReturnType<R(A0)> {};



template <typename F, typename Tuple, unsigned int S= std::tuple_size< typename std::remove_cv<Tuple>::type>::value> 
struct call_impl {
};

#define GET_(x) get<x>(t)
................................................................................
#undef GET_

template <typename F, typename Tuple>
typename FnReturnType<F>::type
apply (F f, Tuple& t) {
    //typedef typename FnReturnType< typename std::remove_pointer<F>::type >::type ret_type;
    typedef typename FnReturnType<F>::type R;


    return call_impl<F,Tuple>::template call<R>( f, t );
}

template <typename F, typename Tuple>
typename FnReturnType<F>::type
apply (F f, Tuple const& t) {
    typedef typename FnReturnType<F>::type R;
................................................................................
Tuple& apply (F f, Tuple& t) {
    tuple_apply_t<F,Tuple>(f,t);
    return t;
}
#endif




} //detail_tuple::
}

#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {
    using cxxomfort::tuple::apply;
}
#endif


#endif

Changes to cxxomfort/cxxomfort/impl/17-void_t.hpp.

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


#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;
    };
}








namespace std {
    using ::cxxomfort::make_void;
}

// "void_t" is an alias, so it doesn't work in c++03
// it has to go in std:: because it is use in template arguments
#if (CXXOMFORT_CXX_STD >= 2011)
namespace std {
template <typename... Ts> 
using void_t = typename make_void<Ts...>::type;
}
#endif




#endif // c++17











#endif









>

<





>



|
>
>
>
>
|
>
>
>

|



|


|
|



>

>


>
>
>
>
>
>
>
>
>
>

>
>
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
#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 {
namespace type_traits {
#if (CXXOMFORT_CXX_STD < 2011)

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

/**
 * @struct make_void
 * @brief Metaprogramming helper that exposes @c void  as a type, for transformations.
 */
}
}

#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {
    using ::cxxomfort::type_traits::make_void;
}

// "void_t" is an alias, so it doesn't work in c++03
// Also it has to go in std:: because it is use in template arguments
#if (CXXOMFORT_CXX_STD >= 2011)
namespace std {
    template <typename... Ts> 
    using void_t = typename make_void<Ts...>::type;
}
#endif

#endif // CXXOMFORT_NO_STD_USING


#endif // c++17

#if defined(DOXYGEN_DOC)
namespace std {
    //! @brief Metaprogramming tool that delivers @c void  as a type.
    //! @ingroup cxx17-backports
    template <typename...> struct make_void { typedef void type; };
    //! @ingroup cxx17-backports
    template <typename... Ts> using void_t = typename make_void<Ts...>::type;

}

#endif

#endif

Changes to cxxomfort/cxxomfort/impl/foreach_artima.hpp.

Changes to cxxomfort/cxxomfort/impl/foreach_gcc.hpp.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// http://www.boost.org/LICENSE_1_0.txt)

//#include <functional>
#include <cxxomfort/config.hpp>
#include <cxxomfort/base/iterator.hpp> // global begin, end
#include <cxxomfort/util/type_traits.hpp>
#include <cxxomfort/util/meta.hpp>
#include <cxxomfort/memory.hpp> // alignof, aligned_storage

namespace cxxomfort {
namespace extras {

struct seq2iter_base {
    operator bool () const { return false; }
};







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// http://www.boost.org/LICENSE_1_0.txt)

//#include <functional>
#include <cxxomfort/config.hpp>
#include <cxxomfort/base/iterator.hpp> // global begin, end
#include <cxxomfort/util/type_traits.hpp>
#include <cxxomfort/util/meta.hpp>
//#include <cxxomfort/memory.hpp> // alignof, aligned_storage

namespace cxxomfort {
namespace extras {

struct seq2iter_base {
    operator bool () const { return false; }
};

Changes to cxxomfort/cxxomfort/impl/forward_list-impl.hpp.

7
8
9
10
11
12
13


14
15
16
17
18
19
20
..
47
48
49
50
51
52
53




54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
..
85
86
87
88
89
90
91












92
93
94
95
96





97
98
99
100
101
102
103
...
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
...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
...
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
...
287
288
289
290
291
292
293

294
295
296
297
298
299
300
...
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
...
413
414
415
416
417
418
419
420
421

422




























423
424
425
426
427
428
429
...
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
...
516
517
518
519
520
521
522
523
524
525


526
527


528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544

545
546
547
548
549
550
551
552
553
554
555
556
557
558

559
560
561
562
563
564
565

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
...
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

644
645
646

647

648
649
650

651

652
653
654
655
656
657
658
...
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
...
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
...
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
#include <utility>
#include <functional>
#include <memory>
#include <algorithm>
#include <stdexcept>
#include <cassert>
#include <new>



#ifdef LDEBUG_ENABLED
#define LDEBUG(msg) if (!LDEBUG_ENABLED) {} \
                   else std::cerr << "[forward_list::"<< msg<< " ]"<< std::endl;
#else
#define LDEBUG(msg) 

................................................................................
    //typedef std::forward_iterator_tag iterator_category;
    typedef T value_type;
    typedef typename std::conditional<Constness, T const&, T&>::type reference;
    typedef typename std::conditional<Constness, T const*, T*>::type pointer;
    typedef typename std::conditional<Constness, /*const*/ sl_node_base *, sl_node_base*>::type nodeptr;
    
    iterator_base (nodeptr x, const nodeptr* s) : cur(x), src(s) {}




    reference       operator*() const { return static_cast<sl_node<T>*>(cur)->value; }
    pointer         operator->() const { return static_cast<sl_node<T>*>(cur)->value; }
    iterator_base&  operator++ () { 
        if (cur) { cur= (nodeptr)(cur->next); }
        return *this; 
    }
    iterator_base   operator++ (int) { iterator_base t(*this); ++*this; return t; }

    operator iterator_base<T, true> () { return iterator_base<T,true>(cur,src); }
    
    friend bool operator== (iterator_base const& a, iterator_base const& b) {
        return a.cur == b.cur;
    }
    friend bool operator!= (iterator_base const& a, iterator_base const& b) {
        return !(a==b);
    }
................................................................................
        ++ini;
    }
}

} // end namespace














// default constructor
template <typename T, typename A>
forward_list<T,A>::forward_list ()
: _p_bb(nullptr), _p_last(nullptr),  alloc(A())  {
}






template <typename T, typename A>
forward_list<T,A>::forward_list (forward_list<T,A> const& l) 
: _p_bb(nullptr), _p_last(nullptr), alloc(l.alloc) {
    if (l.empty()) return;
    this->in_uninitialized_copy(l.begin(), l.end());
}
................................................................................
: alloc(a), _p_bb(nullptr), _p_last(nullptr) {
    this->in_uninitialized_fill_n(count, t);
}

template <typename T, typename A>
template <typename I>
forward_list<T,A>::forward_list (I ini, I fin, A const& a)
: alloc(a), _p_bb(nullptr), _p_last(nullptr) {
    if (ini==fin) return;
    this->in_uninitialized_copy(ini,fin);    
}

/*
// move constructor
template <typename T, typename A>
forward_list<T,A>::forward_list (CXXO_RV_REF(forward_list) p) 
: alloc (std::move(p.alloc)), _p_bb(p._p_bb), _p_last(p._p_last) {
    // relink the list's nodes to this _head
    p._p_last.next = 0;
    p._p_bb= 0;

}
*/

template <typename T, typename A>
forward_list<T,A>::~forward_list () {
    this->clear();
    _p_last=0;
}

// copy assignment
template <typename T, typename A>
forward_list<T,A>& forward_list<T,A>::operator= (CXXO_COPY_ASSIGN_REF(forward_list) p) {
    LDEBUG("copy assignment - called");
    this->clear();
................................................................................
template <typename T, typename A>
typename forward_list<T,A>::reference forward_list<T,A>::front () {
    return *begin();
}


template <typename T, typename A>
typename forward_list<T,A>::const_iterator forward_list<T,A>::before_begin () const {
    return const_iterator(&_p_bb, &_p_last);
}


template <typename T, typename A>
typename forward_list<T,A>::iterator forward_list<T,A>::before_begin () {
    return iterator(&_p_bb, &_p_last);
}


//
// Add elements by the front
//
................................................................................
void forward_list<T,A>::push_front (T const& t) {
    LDEBUG("push_front - called");
    using namespace std;
    //LDEBUG("push_front - allocating and constructing");
    nodeT_t *n = alloc_traits::allocate(alloc,1);
    ::new (&n->value) T(t);
    // if list is empty, we have to update link to last
    if (empty()) _p_last= n;
    this->in_link_after(&_p_bb,n);
    this->_p_bb.next= n;
    LDEBUG("push_front - next -> "<< (void*)_p_bb.next<< " .");
    LDEBUG("push_front - ended H:"<< (void*)this);
}

template <typename T, typename A>
................................................................................
void forward_list<T,A>::push_front (CXXO_RV_REF(T) mv) {

    using namespace std;
    LDEBUG("push_front - allocating and constructing");
    nodeT_t *n = alloc_traits::allocate(alloc,1);
    ::new (&n->value) T( std::move(mv) );
    // if list is empty, we have to update link to last
    if (empty()) _p_last= n;
    this->in_link_after(&_p_bb,n);
    this->_p_bb.next= n;

    LDEBUG("push_front - ended H:"<< (void*)this);
}

#if 0
................................................................................
    if (empty()) {
    LDEBUG("push_back - first element");
        push_front(t);
    } else {
        nodeT_t *n= detail_fwlist::alloc_new(alloc);
        ::new (&n->value) T(t);
        // insert after _end; this will update _end

        this->in_link_after(_p_last,U(n));
    }
    //LDEBUG("push_front - ended H&"<< std::addressof(_head));
}

template <typename T, typename A>
void forward_list<T,A>::push_back (CXXO_RV_REF(T) mv) {
................................................................................
    if (empty()) {
    LDEBUG("push_back (move) - first elem");
        this->push_front(mv);
    } else {
        nodeT_t *n= detail_fwlist::alloc_new(alloc);
        ::new (&n->value) T(std::move(mv));
        // insert after _end; this will update _end

        this->in_link_after(_p_last,U(n));
    }
    //LDEBUG("push_front - ended H&"<< std::addressof(_head));
}

#endif

//

// Remove element from the front
//

/*
 * List is p_bb -> i0 -> i1 -> ... -> null
 * List becomes p_bb -> i1 -> ... -> null
 */

template <typename T, typename A>
void forward_list<T,A>::pop_front () {
    //allocator_type C;
    using namespace std;
    if (empty()) return;
    // unlink the element
    // at this stage, _p_last points to the last element and _p_last->next is the first
    
    node_t* f = _p_bb.next;
    //LDEBUG("pop_front - removing node at next -> "<< (void*)f<< " .");
    _p_bb.next= (f ? f->next : nullptr);
    // we might need to update pointer to last if what we removed was the last element
    if (!_p_bb.next) _p_last= nullptr;

    this->in_destroy(N(f));
}


//
// emplace family of functions
//


#if (CXXOMFORT_CXX_STD >= 2011)
template <typename T, typename A>
template <typename... Args>
void forward_list<T,A>::emplace_front (Args&&... args) {
    using namespace std;
    nodeT_t *n = alloc_traits::allocate(alloc,1);
    ::new (&n->value) T(args...);
    this->in_link_after(&_p_bb,n);
    this->_p_bb.next= n;
}


#else

template <typename T, typename A>
void forward_list<T,A>::emplace_front () {
    using namespace std;
    nodeT_t *n = alloc_traits::allocate(alloc,1);
    ::new (&n->value) T();
    this->in_link_after(&_p_bb,n);
    this->_p_bb.next= n;
................................................................................
    using namespace std;
    nodeT_t *n = alloc_traits::allocate(alloc,1);
    ::new (&n->value) T(a1,a2,a3,a4,a5);
    this->in_link_after(&_p_bb,n);
    this->_p_bb.next= n;
}


#endif






























#if (CXXOMFORT_CXX_STD < 2011)
#if 0
template <typename T, typename A>
template <typename Arg1>
typename forward_list<T,A>::iterator forward_list<T,A>::emplace_after (const_iterator pos
, CXXO_FWD_REF(Arg1) a1) {
    node_t *p = pos.cur;
................................................................................
    nodeT_t *n= std::allocator_traits<node_alloc_t>::allocate(alloc,1) /*new nodeT_t(t)*/;
    ::new (&n->value) T(a1,a2,a3,a4,a5);
    this->in_link_after(p, n);
    return iterator(n);
}

#endif

#else

/*
template <typename T, typename A>
template <typename... Args>
typename forward_list<T,A>::iterator forward_list<T,A>::emplace_after (const_iterator pos, Args&&... a) {
    node_t *p = pos.N;
................................................................................
    return iterator(n);
}

*/

#endif

//
// erase_after
//



// TBD: check for update of last node


template <typename T, typename A>
typename forward_list<T,A>::iterator 
forward_list<T,A>::erase_after (typename forward_list<T,A>::const_iterator pr) {
    iterator ret(begin());
    if (empty()) {
        return end();
    } else {
        LDEBUG("erase_after - begin");
        node_t * p= pr.cur;
        node_t * n= this->in_unlink_after(p);
        if (n)  {
            this->in_destroy(N(n));
        }
        ret= iterator(pr.cur,&_p_last);
        ++ret;
        LDEBUG("erase_after - done");
        return ret;

    }
}

#if 0
template <typename T, typename A>
typename forward_list<T,A>::iterator 
forward_list<T,A>::erase (typename forward_list<T,A>::const_iterator n) {
    iterator ret;
    if (n == end()) ret= end(); // nothing to remove after
    else {
        // make a pointer pr that gets the node that points to n
        node_t prb(0); prb.next= _head;
        node_t * pr= &prb;
        while (pr != _end && pr->next != n.cur) { pr= pr->next; }

        node_t * n= this->in_unlink_after(pr);
        if (n == nullptr) {
            ret= end();
        } else {
            ret= N(n->next);
            // destroy the node n
            this->in_destroy(N(n));

        }
    }
    return ret;
}
#endif

template <typename T, typename A> inline
void forward_list<T,A>::clear () {
    while (!empty()) pop_front();
}

template <typename T, typename A> inline
void forward_list<T,A>::swap (forward_list<T,A>& other) {
    using std::swap;
    swap(_p_bb, other._p_bb);
    swap(_p_last, other._p_last);
    swap( alloc, other.alloc);
}


#if 0
template <typename T, typename A>
template <typename Compare>
void forward_list<T,A>::sort (Compare c) {
    LDEBUG("sort - begin for H&"<< (void*)this);
    if (empty()) return;
    forward_list<T,A> temp;
    // we use insertion sort on the node pointers
    using std::max_element;
    using std::swap;
    nodeT_t *oldh= N(_p_last->next), *oldl= N(_p_last);
    node_t new_head(0);
    node_t orig_before_head(0);
    orig_before_head.next= _p_bb.next;
    LDEBUG("sort -sorting H&"<< (void*)this);

    const_iterator it= begin(), fin= end(), pivot= ++begin();
    size_type i=1;
................................................................................
}

template <typename T, typename A>
void forward_list<T,A>::sort () {
    std::less<T> compare;
    this->sort(compare);
}

#endif


/*
 * remove, remove_if
 */


template <typename T, typename A>
template <typename Condition>
void forward_list<T,A>::remove_if (Condition c) {

    if (empty()) return;
    node_t  *x= _p_bb.next;
    while ( x->next ) {

        if ( c(N(x->next)->value) ) {

            nodeT_t *t = N(in_unlink_after(x));
            if (t) in_destroy(t);
        }

        x= x->next;

    }
}

template <typename T, typename A>
void forward_list<T,A>::remove (T const& t) {
    using namespace std;
    const std::equal_to<T> eq;
................................................................................
        } else {
            ant->next= n;
        }
        ant= n;
    }
    // at this point, 'n' is the last element
    _p_bb.next= pri;
    _p_last= n;
    n->next= nullptr;
    LDEBUG("in_uninitialized_copy -done");
}


template <typename T, typename A>
void forward_list<T,A>::in_uninitialized_fill_n (size_t count, T const& t) {
................................................................................
        } else {
            ant->next= n;
        }
        ant= n;
    }
    // at this point, 'n' is the last element
    _p_bb.next= pri;
    _p_last= n;
    n->next= nullptr;
    LDEBUG("in_uninitialized_fill -done");
}

template <typename T, typename A>
void forward_list<T,A>::in_link_after (node_t * const pre, node_t *n) {
    // list is ....-> pre -> s
    // list becomes ....-> pre -> n -> s
    n->next= pre->next;
    if (pre==_p_last) n=_p_last;
    pre->next= n;

}

// Unlinks node pr->next from the list and return it as ret
template <typename T, typename A>
typename forward_list<T,A>::node_t * forward_list<T,A>::in_unlink_after (node_t *pr) {
    // list is ...-> pr -> u -> s
    // list becomes ...-> pr -> s
    // if pre is last-sentry, we do nothing
    // if pre is before_begin, we want to unlink from the front
    if (empty()) {
        return nullptr;
    }
    
    node_t *ret= pr->next;
    // actual node exists beyond pr
    if (!ret) { return ret; }
    if (pr==&_p_bb) {
        _p_bb.next= (_p_bb.next ? _p_bb.next->next : nullptr);
    } else {
        // list is last -> 1 -> 2 -> ... -> pr -> u -> s ->
        if (pr->next) pr->next= pr->next->next;
    }
    ret->next= nullptr; // remove dangling link
    return ret;
}
................................................................................
template <typename T, typename A> inline
typename forward_list<T,A>::node_t* forward_list<T,A>::in_destroy (nodeT_t *p) {
    if (!p) return p;
    (p->value).~T();
    alloc_traits::deallocate(alloc,p,1);
    return p;
}


template <typename T1, typename A1, typename T2, typename A2>
inline bool operator== (forward_list<T1,A1> const& a, forward_list<T2,A2> const& b) {
    using std::equal;
    return a.size() == b.size() ? equal(a.begin(), a.end(), b.begin()) : false;
}








>
>







 







>
>
>
>







>
|







 







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







 







|




<





|
|
>
|
<




<







 







|





|







 







|







 







<







 







>







 







>







|
>
|
<
<
<
<
<




<



<
|
|
<
|
<
<
<



|
|
|
|
|
|
|










>
|
>







 







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







 







<







 







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












<










|







 







<











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







 







|







 







|









<
|
<







<
<
|
|
|
<
|
|
<
|
|







 







<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
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
..
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
...
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
...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
...
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
...
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342





343
344
345
346

347
348
349

350
351

352



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
...
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
...
522
523
524
525
526
527
528

529
530
531
532
533
534
535
...
558
559
560
561
562
563
564
565
566

567
568
569

570
571
572
573
574


575
576
577
578



579




580
581











582

583
584





585
586
587
588

589


590
591
592
593
594
595
596
597
598
599
600
601
602

603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
...
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668

669
670
671
672
673
674
675
676
677
678
...
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
...
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771

772

773
774
775
776
777
778
779


780
781
782

783
784

785
786
787
788
789
790
791
792
793
...
795
796
797
798
799
800
801

802
803
804
805
806
807
808
#include <utility>
#include <functional>
#include <memory>
#include <algorithm>
#include <stdexcept>
#include <cassert>
#include <new>
// for debug only
//#include <iostream>

#ifdef LDEBUG_ENABLED
#define LDEBUG(msg) if (!LDEBUG_ENABLED) {} \
                   else std::cerr << "[forward_list::"<< msg<< " ]"<< std::endl;
#else
#define LDEBUG(msg) 

................................................................................
    //typedef std::forward_iterator_tag iterator_category;
    typedef T value_type;
    typedef typename std::conditional<Constness, T const&, T&>::type reference;
    typedef typename std::conditional<Constness, T const*, T*>::type pointer;
    typedef typename std::conditional<Constness, /*const*/ sl_node_base *, sl_node_base*>::type nodeptr;
    
    iterator_base (nodeptr x, const nodeptr* s) : cur(x), src(s) {}
    // constructs a const iterator from a non-const one
    //explicit iterator_base (iterator_base<T,false> const& x
    //, typename std::enable_if< Constness==true, bool >::type * =0) 
    //: cur(x.cur), src(x.src) {}
    reference       operator*() const { return static_cast<sl_node<T>*>(cur)->value; }
    pointer         operator->() const { return static_cast<sl_node<T>*>(cur)->value; }
    iterator_base&  operator++ () { 
        if (cur) { cur= (nodeptr)(cur->next); }
        return *this; 
    }
    iterator_base   operator++ (int) { iterator_base t(*this); ++*this; return t; }
    // returns a const_iterator view where requested.
    operator iterator_base<T, true> () const { return iterator_base<T,true>(cur,src); }
    
    friend bool operator== (iterator_base const& a, iterator_base const& b) {
        return a.cur == b.cur;
    }
    friend bool operator!= (iterator_base const& a, iterator_base const& b) {
        return !(a==b);
    }
................................................................................
        ++ini;
    }
}

} // end namespace



template <typename T, typename A>
void forward_list<T,A>::in_report_list () {
    using namespace std;
    node_t* i= (&_p_bb)->next;
    while (i) {
        //cout<< "Node &"<< (void*)i<< " ->next &"<< (void*)(i->next)<< " ->value: ["<< N(i)->value<< "]"<< endl;
        i= i->next;
    }
    //cout<< "Node done."<< endl;
}

// default constructor
template <typename T, typename A>
forward_list<T,A>::forward_list () CXXO_NOEXCEPT
: _p_bb(nullptr), _p_last(nullptr),  alloc(A())  {
}

template <typename T, typename A>
forward_list<T,A>::forward_list (A const& a)
: _p_bb(nullptr), _p_last(nullptr),  alloc(a)  {
}

template <typename T, typename A>
forward_list<T,A>::forward_list (forward_list<T,A> const& l) 
: _p_bb(nullptr), _p_last(nullptr), alloc(l.alloc) {
    if (l.empty()) return;
    this->in_uninitialized_copy(l.begin(), l.end());
}
................................................................................
: alloc(a), _p_bb(nullptr), _p_last(nullptr) {
    this->in_uninitialized_fill_n(count, t);
}

template <typename T, typename A>
template <typename I>
forward_list<T,A>::forward_list (I ini, I fin, A const& a)
: _p_bb(nullptr), _p_last(nullptr), alloc(a) {
    if (ini==fin) return;
    this->in_uninitialized_copy(ini,fin);    
}


// move constructor
template <typename T, typename A>
forward_list<T,A>::forward_list (CXXO_RV_REF(forward_list) p) 
: alloc (std::move(p.alloc)), _p_bb(p._p_bb), _p_last(p._p_last) {
    // relink the list's nodes to this _head
    //p._p_last.next = 0;
    p._p_bb= 0;
    p.alloc= A();
}


template <typename T, typename A>
forward_list<T,A>::~forward_list () {
    this->clear();

}

// copy assignment
template <typename T, typename A>
forward_list<T,A>& forward_list<T,A>::operator= (CXXO_COPY_ASSIGN_REF(forward_list) p) {
    LDEBUG("copy assignment - called");
    this->clear();
................................................................................
template <typename T, typename A>
typename forward_list<T,A>::reference forward_list<T,A>::front () {
    return *begin();
}


template <typename T, typename A>
typename forward_list<T,A>::const_iterator forward_list<T,A>::before_begin () const CXXO_NOEXCEPT {
    return const_iterator(&_p_bb, &_p_last);
}


template <typename T, typename A>
typename forward_list<T,A>::iterator forward_list<T,A>::before_begin () CXXO_NOEXCEPT {
    return iterator(&_p_bb, &_p_last);
}


//
// Add elements by the front
//
................................................................................
void forward_list<T,A>::push_front (T const& t) {
    LDEBUG("push_front - called");
    using namespace std;
    //LDEBUG("push_front - allocating and constructing");
    nodeT_t *n = alloc_traits::allocate(alloc,1);
    ::new (&n->value) T(t);
    // if list is empty, we have to update link to last
    //if (empty()) _p_last= n;
    this->in_link_after(&_p_bb,n);
    this->_p_bb.next= n;
    LDEBUG("push_front - next -> "<< (void*)_p_bb.next<< " .");
    LDEBUG("push_front - ended H:"<< (void*)this);
}

template <typename T, typename A>
................................................................................
void forward_list<T,A>::push_front (CXXO_RV_REF(T) mv) {

    using namespace std;
    LDEBUG("push_front - allocating and constructing");
    nodeT_t *n = alloc_traits::allocate(alloc,1);
    ::new (&n->value) T( std::move(mv) );
    // if list is empty, we have to update link to last

    this->in_link_after(&_p_bb,n);
    this->_p_bb.next= n;

    LDEBUG("push_front - ended H:"<< (void*)this);
}

#if 0
................................................................................
    if (empty()) {
    LDEBUG("push_back - first element");
        push_front(t);
    } else {
        nodeT_t *n= detail_fwlist::alloc_new(alloc);
        ::new (&n->value) T(t);
        // insert after _end; this will update _end
        // NOTE: remove use of _p_last
        this->in_link_after(_p_last,U(n));
    }
    //LDEBUG("push_front - ended H&"<< std::addressof(_head));
}

template <typename T, typename A>
void forward_list<T,A>::push_back (CXXO_RV_REF(T) mv) {
................................................................................
    if (empty()) {
    LDEBUG("push_back (move) - first elem");
        this->push_front(mv);
    } else {
        nodeT_t *n= detail_fwlist::alloc_new(alloc);
        ::new (&n->value) T(std::move(mv));
        // insert after _end; this will update _end
        // NOTE: remove use of _p_last
        this->in_link_after(_p_last,U(n));
    }
    //LDEBUG("push_front - ended H&"<< std::addressof(_head));
}

#endif

/*
 * pop_front
 * Remove element from the front





 */

template <typename T, typename A>
void forward_list<T,A>::pop_front () {

    using namespace std;
    if (empty()) return;
    // unlink the element

    
    node_t* f = _p_bb.next;

    _p_bb.next= (f ? f->next : nullptr);



    this->in_destroy(N(f));
}

/*
 * emplace_front
 * Construct new element at the front
 */

#if (CXXOMFORT_CXX_STD >= 2011)
/*
template <typename T, typename A>
template <typename... Args>
void forward_list<T,A>::emplace_front (Args&&... args) {
    using namespace std;
    nodeT_t *n = alloc_traits::allocate(alloc,1);
    ::new (&n->value) T(args...);
    this->in_link_after(&_p_bb,n);
    this->_p_bb.next= n;
}

*/
#else
    #if 0
template <typename T, typename A>
void forward_list<T,A>::emplace_front () {
    using namespace std;
    nodeT_t *n = alloc_traits::allocate(alloc,1);
    ::new (&n->value) T();
    this->in_link_after(&_p_bb,n);
    this->_p_bb.next= n;
................................................................................
    using namespace std;
    nodeT_t *n = alloc_traits::allocate(alloc,1);
    ::new (&n->value) T(a1,a2,a3,a4,a5);
    this->in_link_after(&_p_bb,n);
    this->_p_bb.next= n;
}


    #endif
#endif

/*
 * insert_after
 * 
 */

template <typename T, typename A>
typename forward_list<T,A>::iterator 
forward_list<T,A>::insert_after (const_iterator pos, T const& t) {
    node_t *p = pos.cur; // pos.N 
    //assert (p != &_head && "list::insert_after can not use _head node");
    nodeT_t *n= std::allocator_traits<node_alloc_t>::allocate(alloc,1) /*new nodeT_t(t)*/;
    ::new (&n->value) T(t);
    if (pos == this->end()) {
        node_t* ci= this->begin().cur;
        while (ci->next != nullptr) { ci=ci->next; }
        this->in_link_after(ci, n);
    } else {
        this->in_link_after(p, n);
    }
    return iterator(U(n), &_p_last);
}


/*
 * emplace_after
 * Construct element in a new node after a specific node
 */

#if (CXXOMFORT_CXX_STD < 2011)
#if 0
template <typename T, typename A>
template <typename Arg1>
typename forward_list<T,A>::iterator forward_list<T,A>::emplace_after (const_iterator pos
, CXXO_FWD_REF(Arg1) a1) {
    node_t *p = pos.cur;
................................................................................
    nodeT_t *n= std::allocator_traits<node_alloc_t>::allocate(alloc,1) /*new nodeT_t(t)*/;
    ::new (&n->value) T(a1,a2,a3,a4,a5);
    this->in_link_after(p, n);
    return iterator(n);
}

#endif

#else

/*
template <typename T, typename A>
template <typename... Args>
typename forward_list<T,A>::iterator forward_list<T,A>::emplace_after (const_iterator pos, Args&&... a) {
    node_t *p = pos.N;
................................................................................
    return iterator(n);
}

*/

#endif

/*
 * erase_after

 * Erase the element(s) placed after a specific node.
 * returns: iterator following the erased element
 * 

 */

template <typename T, typename A>
typename forward_list<T,A>::iterator 
forward_list<T,A>::erase_after (typename forward_list<T,A>::const_iterator P) {


    // list is p -> n -> x
    // list becomes p -> x
    using namespace std;
    node_t * p= P.cur;



    




    if (p==nullptr || p->next==nullptr) return this->end();
    











    //node_t *n;

    //n= p->next;
    nodeT_t *E = N(this->in_unlink_after(p));





    this->in_destroy(E);
    return iterator(p->next, &_p_last);
    
}




template <typename T, typename A>
void forward_list<T,A>::clear () {
    while (!empty()) pop_front();
}

template <typename T, typename A> inline
void forward_list<T,A>::swap (forward_list<T,A>& other) {
    using std::swap;
    swap(_p_bb, other._p_bb);
    swap(_p_last, other._p_last);
    swap( alloc, other.alloc);
}


#if 0
template <typename T, typename A>
template <typename Compare>
void forward_list<T,A>::sort (Compare c) {
    LDEBUG("sort - begin for H&"<< (void*)this);
    if (empty()) return;
    forward_list<T,A> temp;
    // we use insertion sort on the node pointers
    using std::max_element;
    using std::swap;
    nodeT_t *oldh= N(_p_bb.next);
    node_t new_head(0);
    node_t orig_before_head(0);
    orig_before_head.next= _p_bb.next;
    LDEBUG("sort -sorting H&"<< (void*)this);

    const_iterator it= begin(), fin= end(), pivot= ++begin();
    size_type i=1;
................................................................................
}

template <typename T, typename A>
void forward_list<T,A>::sort () {
    std::less<T> compare;
    this->sort(compare);
}

#endif


/*
 * remove, remove_if
 */


template <typename T, typename A>
template <typename Condition>
void forward_list<T,A>::remove_if (Condition c) {
    using namespace std;
    if (empty()) return;
    node_t  *x= _p_bb.next;
    while ( x->next != nullptr ) {
        //this->in_report_list();
        if ( c(N(x->next)->value) ) {
            //cout<< "Node to remove is &"<< (void*)(x->next)<< " with value "<< N(x->next)->value <<"."<< endl;
            nodeT_t *t = N(in_unlink_after(x));
            if (t) in_destroy(t);

        } else {
            x= x->next;
        }
    }
}

template <typename T, typename A>
void forward_list<T,A>::remove (T const& t) {
    using namespace std;
    const std::equal_to<T> eq;
................................................................................
        } else {
            ant->next= n;
        }
        ant= n;
    }
    // at this point, 'n' is the last element
    _p_bb.next= pri;
    //_p_last= n;
    n->next= nullptr;
    LDEBUG("in_uninitialized_copy -done");
}


template <typename T, typename A>
void forward_list<T,A>::in_uninitialized_fill_n (size_t count, T const& t) {
................................................................................
        } else {
            ant->next= n;
        }
        ant= n;
    }
    // at this point, 'n' is the last element
    _p_bb.next= pri;
    //_p_last= n;
    n->next= nullptr;
    LDEBUG("in_uninitialized_fill -done");
}

template <typename T, typename A>
void forward_list<T,A>::in_link_after (node_t * const pre, node_t *n) {
    // list is ....-> pre -> s
    // list becomes ....-> pre -> n -> s
    n->next= pre->next;

    pre->next= n;

}

// Unlinks node pr->next from the list and return it as ret
template <typename T, typename A>
typename forward_list<T,A>::node_t * forward_list<T,A>::in_unlink_after (node_t *pr) {
    // list is ...-> pr -> u -> s
    // list becomes ...-> pr -> s


    if (empty() || pr->next == nullptr) {
        return nullptr;
    }

    node_t *ret= pr->next;
    // actual node exists beyond pr

    if (pr==&_p_bb) {
        _p_bb.next= _p_bb.next->next;
    } else {
        // list is last -> 1 -> 2 -> ... -> pr -> u -> s ->
        if (pr->next) pr->next= pr->next->next;
    }
    ret->next= nullptr; // remove dangling link
    return ret;
}
................................................................................
template <typename T, typename A> inline
typename forward_list<T,A>::node_t* forward_list<T,A>::in_destroy (nodeT_t *p) {
    if (!p) return p;
    (p->value).~T();
    alloc_traits::deallocate(alloc,p,1);
    return p;
}


template <typename T1, typename A1, typename T2, typename A2>
inline bool operator== (forward_list<T1,A1> const& a, forward_list<T2,A2> const& b) {
    using std::equal;
    return a.size() == b.size() ? equal(a.begin(), a.end(), b.begin()) : false;
}

Deleted cxxomfort/cxxomfort/impl/make_unique.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
#ifndef CXXOMFORT_UTIL_MAKE_UNIQUE_HPP
#define CXXOMFORT_UTIL_MAKE_UNIQUE_HPP

#include "../base.hpp"
#include "../impl/unique_ptr.hpp"

// this is included after unique_ptr

// Add make_unique

namespace std {

#if (CXXOMFORT_CXX_STD >= 2011)

template <typename T, typename ...Args> inline
unique_ptr<T> make_unique (Args&&... args) {
    return std::unique_ptr<T>( new T(std::forward<Args>(args)... ) );
}

#else
template <typename T> inline
unique_ptr<T> make_unique () {
    return unique_ptr<T> (new T());
}
template <typename T, typename A1> inline
unique_ptr<T> make_unique (CXXO_FWD_REF(A1) a1) {
    return unique_ptr<T> (new T( forward<A1>(a1) ));
}
template <typename T, typename A1, typename A2> inline
unique_ptr<T> make_unique (CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2) {
    return unique_ptr<T> (new T( forward<A1>(a1), forward<A2>(a2) ));
}
template <typename T, typename A1, typename A2, typename A3> inline
unique_ptr<T> make_unique (CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2, CXXO_FWD_REF(A3) a3) {
    return unique_ptr<T> (new T( 
       forward<A1>(a1), forward<A2>(a2), forward<A3>(a3) ));
}
template <typename T, typename A1, typename A2, typename A3, typename A4> inline
unique_ptr<T> make_unique (CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2, CXXO_FWD_REF(A3) a3, CXXO_FWD_REF(A4) a4) {
    return unique_ptr<T> (new T(
       forward<A1>(a1), forward<A2>(a2), forward<A3>(a3)
     , forward<A4>(a4) ));
}
template <typename T, typename A1, typename A2, typename A3, typename A4, typename A5> inline
unique_ptr<T> make_unique (CXXO_FWD_REF(A1) a1, CXXO_FWD_REF(A2) a2, CXXO_FWD_REF(A3) a3, CXXO_FWD_REF(A4) a4, CXXO_FWD_REF(A5) a5) {
    return unique_ptr<T> (new T(
      forward<A1>(a1), forward<A2>(a2), forward<A3>(a3), 
      forward<A4>(a4), forward<A5>(a5) ));
}

#endif
}

#endif

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














































































































Changes to cxxomfort/cxxomfort/impl/n3668_exchange.hpp.

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


#if (CXXOMFORT_CXX_STD < 2014)
#define CXXOMFORT_IMPLEMENTS_n3668 1

namespace cxxomfort {


/**
 * @brief Replaces a variable's value, returns the old value.
 * @sa N3668
 * @ingroup utility
 * @ref cxx03-backports
 * @ref cxx11-backports
 */
template <typename T, typename U>
T exchange (T& obj, CXXO_RV_REF(U) nval) {
    T oval = std::move(obj);
    obj= std::forward<U>(nval);
    return oval;
}

/**
 * @brief Replaces a variable's value, returns the old value.
 * @sa N3668
 * @ingroup utility
 * @ref cxx03-backports
 * @ref cxx11-backports
 */
template <typename T>
T exchange (T& obj, CXXO_RV_REF(T) nval) {
    T oval = std::move(obj);
    obj= std::forward<T>(nval);
    return oval;
}


} //cxxomfort::

#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {
    //! @ingroup utility
    using ::cxxomfort::exchange;
} // std::
#endif // std using

#endif


#endif







>
>



|
|
<











|
|
<








>




|
|







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


#if (CXXOMFORT_CXX_STD < 2014)
#define CXXOMFORT_IMPLEMENTS_n3668 1

namespace cxxomfort {
namespace utility {

/**
 * @brief Replaces a variable's value, returns the old value.
 * @sa N3668
 * @ingroup cxx14-backports
 * @ref utility

 */
template <typename T, typename U>
T exchange (T& obj, CXXO_RV_REF(U) nval) {
    T oval = std::move(obj);
    obj= std::forward<U>(nval);
    return oval;
}

/**
 * @brief Replaces a variable's value, returns the old value.
 * @sa N3668
 * @ingroup cxx14-backports
 * @ref utility

 */
template <typename T>
T exchange (T& obj, CXXO_RV_REF(T) nval) {
    T oval = std::move(obj);
    obj= std::forward<T>(nval);
    return oval;
}

} //utility::
} //cxxomfort::

#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {
    //! @ingroup cxx14-backports
    using ::cxxomfort::utility::exchange;
} // std::
#endif // std using

#endif


#endif

Changes to cxxomfort/cxxomfort/impl/n3928_static_assert.hpp.

Changes to cxxomfort/cxxomfort/impl/n4031_make_array.hpp.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181

182
183
184
185
186
187
188
// See proposal:  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4031.html
//
// http://stackoverflow.com/questions/6114067/how-to-emulate-c-array-initialization-int-arr-e1-e2-e3-behaviou
//

namespace cxxomfort {

#if (CXXOMFORT_CXX_STD >= 2011) 

// zero-size array. Needs the type given explicitly.
template <typename T>
constexpr std::array<T,0>
make_array () {
    return {{ }};
}

namespace detail_make_array {
    template <typename T>
    struct id { typedef T type; };
    
}


// Here type can be deduced (via common_type) or given explicitly.
template <typename V = void, typename... T>
constexpr auto 
make_array (T&&... t)
-> std::array <
    typename std::conditional<
        std::is_void<V>::value, typename std::common_type<T...>::type, V
    >::type
, sizeof...(T)>
{
    using namespace std;
//    typedef typename std::conditional<
//        std::is_void<V>::value, typename std::common_type<T...>::type, V
//    >::type A_Type;
    return {{ std::forward<T>(t)... }};
}

#else
// c++03 versions, with forwarding emulation
// for this implementation, the type should be given explicitly

template <typename T> inline
std::array<T,0> make_array() {
    return std::array<T,0>();
}

template <typename T> inline
std::array<T,1> make_array(CXXO_FWD_REF(T) t1) {
    std::array<T,1> ret= { {std::forward<T>(t1)} };
    return ret;
}

// make_array : 2 args

template <typename V, typename T0, typename T1> inline
std::array<V,2>  
make_array (CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1
) {
	using namespace std;
    array<V,2> ret= { {forward<T0>(t0), forward<T1>(t1)} };
    return ret;
}

// make_array : 3 args

template <typename V, typename T0, typename T1, typename T2> inline
std::array<V,3> 
make_array (CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
) {
    using namespace std;
    //enum { test = ~is_same<V,T0>::value or ~is_same<V,T2>::value };
    //static_assert( test, "make_array<V,3>: same types" );
    array<V,3> ret= { {forward<T0>(t0), forward<T1>(t1), forward<T2>(t2)} };
    return ret;
}

template <typename T> inline 
std::array< typename std::decay<T const>::type ,3>
make_array (T const& t0, T const& t1, T const& t2
) {
    using namespace std;
    array< typename std::decay<T const>::type ,3> ret= { {t0, t1, t2 } };
    return ret;
}

// make_array : 4 args

template <typename V, typename T0, typename T1, typename T2, typename T3> inline
std::array<V,4> 
make_array (CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
        , CXXO_FWD_REF(T3) t3
) {
    using namespace std;
    array<V,4> ret= { {forward<T0>(t0),forward<T1>(t1),forward<T2>(t2)
        , forward<T3>(t3)} };
    return ret;
}

template <typename T> inline 
std::array< typename std::decay<T>::type ,4>
make_array (T& t0, T& t1, T& t2, T& t3
) {
    using namespace std;
    array< typename std::decay<T>::type ,4> ret= { {t0, t1, t2, t3 } };
    return ret;
}


// make_array : 5 args

template <typename V, typename T0, typename T1, typename T2, typename T3, typename T4> inline
std::array<V,5> 
make_array (CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
        , CXXO_FWD_REF(T3) t3, CXXO_FWD_REF(T4) t4
) {
    using namespace std;
    array<V,5> ret= { {forward<T0>(t0),forward<T1>(t1),forward<T2>(t2)
        , forward<T3>(t3), forward<T4>(t4)} };
    return ret;
}


// make_array : 6 args

template <typename V, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5> inline
std::array<V,6> make_array(
    CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
  , CXXO_FWD_REF(T3) t3, CXXO_FWD_REF(T4) t4, CXXO_FWD_REF(T5) t5
) {
    using namespace std;
    std::array<V,6> ret= { {forward<T0>(t0), forward<T1>(t1), forward<T2>(t2)
      , forward<T3>(t3), forward<T4>(t4), forward<T5>(t5)} };
    return ret;
}

// make_array : 7 args

template <typename V, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> inline
std::array<V,7> make_array(
    CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
  , CXXO_FWD_REF(T3) t3, CXXO_FWD_REF(T4) t4, CXXO_FWD_REF(T5) t5
  , CXXO_FWD_REF(T6) t6
) {
    using namespace std;
    std::array<V,7> ret= { {forward<T0>(t0), forward<T1>(t1), forward<T2>(t2)
      , forward<T3>(t3), forward<T4>(t4), forward<T5>(t5)
      , forward<T6>(t6)} };
    return ret;
}

// make_array : 8 args

template <typename V, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> inline
std::array<V,8> make_array(
    CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
  , CXXO_FWD_REF(T3) t3, CXXO_FWD_REF(T4) t4, CXXO_FWD_REF(T5) t5
  , CXXO_FWD_REF(T6) t6, CXXO_FWD_REF(T7) t7
) {
    using namespace std;
    std::array<V,8> ret= { {forward<T0>(t0), forward<T1>(t1), forward<T2>(t2)
      , forward<T3>(t3), forward<T4>(t4), forward<T5>(t5)
      , forward<T6>(t6), forward<T7>(t7) } };
    return ret;
}


#endif // c++ mode


// to_array
#if (CXXOMFORT_CXX_STD >= 2011) || ((CXXO_COMPILER_SUPPORT_auto==1 && CXXO_COMPILER_SUPPORT_rvref==1 && CXXO_COMPILER_SUPPORT_constexpr==1))

namespace detail_array {

    template <size_t... I>







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







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// See proposal:  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4031.html
//
// http://stackoverflow.com/questions/6114067/how-to-emulate-c-array-initialization-int-arr-e1-e2-e3-behaviou
//

namespace cxxomfort {

#if (CXXOMFORT_CXX_STD >= 2011 && CXXOMFORT_CXX_STD < 2017) 

    // zero-size array. Needs the type given explicitly.
    template <typename T>
    constexpr std::array<T,0>
    make_array () {
        return {{ }};
    }

    namespace detail_make_array {
        template <typename T>
        struct id { typedef T type; };
        
    }


    // Here type can be deduced (via common_type) or given explicitly.
    template <typename V = void, typename... T>
    constexpr auto 
    make_array (T&&... t)
    -> std::array <
        typename std::conditional<
            std::is_void<V>::value, typename std::common_type<T...>::type, V
        >::type
    , sizeof...(T)>
    {
        using namespace std;
    //    typedef typename std::conditional<
    //        std::is_void<V>::value, typename std::common_type<T...>::type, V
    //    >::type A_Type;
        return {{ std::forward<T>(t)... }};
    }

#else
    // c++03 versions, with forwarding emulation
    // for this implementation, the type should be given explicitly

    template <typename T> inline
    std::array<T,0> make_array() {
        return std::array<T,0>();
    }

    template <typename T> inline
    std::array<T,1> make_array(CXXO_FWD_REF(T) t1) {
        std::array<T,1> ret= { {std::forward<T>(t1)} };
        return ret;
    }

    // make_array : 2 args

    template <typename V, typename T0, typename T1> inline
    std::array<V,2>  
    make_array (CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1
    ) {
        using namespace std;
        array<V,2> ret= { {forward<T0>(t0), forward<T1>(t1)} };
        return ret;
    }

    // make_array : 3 args

    template <typename V, typename T0, typename T1, typename T2> inline
    std::array<V,3> 
    make_array (CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
    ) {
        using namespace std;
        //enum { test = ~is_same<V,T0>::value or ~is_same<V,T2>::value };
        //static_assert( test, "make_array<V,3>: same types" );
        array<V,3> ret= { {forward<T0>(t0), forward<T1>(t1), forward<T2>(t2)} };
        return ret;
    }

    template <typename T> inline 
    std::array< typename std::decay<T const>::type ,3>
    make_array (T const& t0, T const& t1, T const& t2
    ) {
        using namespace std;
        array< typename std::decay<T const>::type ,3> ret= { {t0, t1, t2 } };
        return ret;
    }

    // make_array : 4 args

    template <typename V, typename T0, typename T1, typename T2, typename T3> inline
    std::array<V,4> 
    make_array (CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
            , CXXO_FWD_REF(T3) t3
    ) {
        using namespace std;
        array<V,4> ret= { {forward<T0>(t0),forward<T1>(t1),forward<T2>(t2)
            , forward<T3>(t3)} };
        return ret;
    }

    template <typename T> inline 
    std::array< typename std::decay<T>::type ,4>
    make_array (T& t0, T& t1, T& t2, T& t3
    ) {
        using namespace std;
        array< typename std::decay<T>::type ,4> ret= { {t0, t1, t2, t3 } };
        return ret;
    }


    // make_array : 5 args

    template <typename V, typename T0, typename T1, typename T2, typename T3, typename T4> inline
    std::array<V,5> 
    make_array (CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
            , CXXO_FWD_REF(T3) t3, CXXO_FWD_REF(T4) t4
    ) {
        using namespace std;
        array<V,5> ret= { {forward<T0>(t0),forward<T1>(t1),forward<T2>(t2)
            , forward<T3>(t3), forward<T4>(t4)} };
        return ret;
    }


    // make_array : 6 args

    template <typename V, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5> inline
    std::array<V,6> make_array(
        CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
      , CXXO_FWD_REF(T3) t3, CXXO_FWD_REF(T4) t4, CXXO_FWD_REF(T5) t5
    ) {
        using namespace std;
        std::array<V,6> ret= { {forward<T0>(t0), forward<T1>(t1), forward<T2>(t2)
          , forward<T3>(t3), forward<T4>(t4), forward<T5>(t5)} };
        return ret;
    }

    // make_array : 7 args

    template <typename V, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> inline
    std::array<V,7> make_array(
        CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
      , CXXO_FWD_REF(T3) t3, CXXO_FWD_REF(T4) t4, CXXO_FWD_REF(T5) t5
      , CXXO_FWD_REF(T6) t6
    ) {
        using namespace std;
        std::array<V,7> ret= { {forward<T0>(t0), forward<T1>(t1), forward<T2>(t2)
          , forward<T3>(t3), forward<T4>(t4), forward<T5>(t5)
          , forward<T6>(t6)} };
        return ret;
    }

    // make_array : 8 args

    template <typename V, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> inline
    std::array<V,8> make_array(
        CXXO_FWD_REF(T0) t0, CXXO_FWD_REF(T1) t1, CXXO_FWD_REF(T2) t2
      , CXXO_FWD_REF(T3) t3, CXXO_FWD_REF(T4) t4, CXXO_FWD_REF(T5) t5
      , CXXO_FWD_REF(T6) t6, CXXO_FWD_REF(T7) t7
    ) {
        using namespace std;
        std::array<V,8> ret= { {forward<T0>(t0), forward<T1>(t1), forward<T2>(t2)
          , forward<T3>(t3), forward<T4>(t4), forward<T5>(t5)
          , forward<T6>(t6), forward<T7>(t7) } };
        return ret;
    }


// end c++ mode
#endif

// to_array
#if (CXXOMFORT_CXX_STD >= 2011) || ((CXXO_COMPILER_SUPPORT_auto==1 && CXXO_COMPILER_SUPPORT_rvref==1 && CXXO_COMPILER_SUPPORT_constexpr==1))

namespace detail_array {

    template <size_t... I>

Changes to cxxomfort/cxxomfort/impl/pseudovariadic.hpp.

Changes to cxxomfort/cxxomfort/impl/regex-esc.hpp.

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef CXXOMFORT_EXTRAS_REGEX_HPP
#define CXXOMFORT_EXTRAS_REGEX_HPP
#include <cxxomfort/config.hpp>
/**
 * @file extras/regex.hpp
 * @brief Escape de secuencias regex
 * 
 * Awesome trick to write raw regexes in C++03, also works in C++11:
 * http://stackoverflow.com/questions/3978351/how-to-avoid-backslash-escape-when-writing-regular-expression-in-c-c
 * 
**/





|







1
2
3
4
5
6
7
8
9
10
11
12
#ifndef CXXOMFORT_EXTRAS_REGEX_HPP
#define CXXOMFORT_EXTRAS_REGEX_HPP
#include <cxxomfort/config.hpp>
/**
 * @file
 * @brief Escape de secuencias regex
 * 
 * Awesome trick to write raw regexes in C++03, also works in C++11:
 * http://stackoverflow.com/questions/3978351/how-to-avoid-backslash-escape-when-writing-regular-expression-in-c-c
 * 
**/

Changes to cxxomfort/cxxomfort/impl/seq_.hpp.

1
2



3
4
5
6
7
8
9
#ifndef CXXOMFORT_IMPL_SEQ_HPP
#define CXXOMFORT_IMPL_SEQ_HPP




// implementation of seq_<T>(), ...

#include <valarray>

namespace cxxomfort {



>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
#ifndef CXXOMFORT_IMPL_SEQ_HPP
#define CXXOMFORT_IMPL_SEQ_HPP
/**
 * @file
 */

// implementation of seq_<T>(), ...

#include <valarray>

namespace cxxomfort {

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




1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
...
342
343
344
345
346
347
348






//#include "../extras/optional.hpp"

namespace cxxomfort {
namespace string {
namespace detail_string {

const struct no_t {
    template <typename Ch, typename Tr, typename Alloc>
    friend std::basic_ostringstream<Ch,Tr,Alloc>& 
    operator<< (std::basic_ostringstream<Ch,Tr,Alloc>& os, no_t const& n) {

        return os;
}

} noitem = {};


template <
................................................................................
std::string  to_string
(T0 const& t0, T1 const& t1) {
    return to_basic_string_defaults<char>(t0,t1);
}

} // string
} // cxxomfort


>
>
>











>







 







>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
346
347
348
349
350
351
352
353
354
#ifndef CXXOMFORT_IMPL_TO_BASIC_STRING_03_HPP
#define CXXOMFORT_IMPL_TO_BASIC_STRING_03_HPP


//#include "../extras/optional.hpp"

namespace cxxomfort {
namespace string {
namespace detail_string {

const struct no_t {
    template <typename Ch, typename Tr, typename Alloc>
    friend std::basic_ostringstream<Ch,Tr,Alloc>& 
    operator<< (std::basic_ostringstream<Ch,Tr,Alloc>& os, no_t const& n) {
        (void)n;
        return os;
}

} noitem = {};


template <
................................................................................
std::string  to_string
(T0 const& t0, T1 const& t1) {
    return to_basic_string_defaults<char>(t0,t1);
}

} // string
} // cxxomfort

#endif

Changes to cxxomfort/cxxomfort/impl/to_basic_string_variadic.hpp.

1
2
3
4
5
6
7
8
9
10
11
..
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#ifndef CXXOMFORT_IMPL_TO_BASIC_STRING_V_HPP
#define CXXOMFORT_IMPL_TO_BASIC_STRING_V_HPP
/**
 * @file cxxomfort/impl/to_basic_string_variadic.hpp
 * @brief Implements the variadic "to_basic_string" proposal in http://open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0117r0.html .
 *
 * 
 * Interfaces defined in this file:
 * 
 * In namespace cxxomfort::string:
 * 
................................................................................
#endif

#if defined(DOXYGEN_DOC)

/**
 * @brief Provides a string expression of its arguments.
 * @ingroup independent-utilities
 * @ingroup cxx03-backports
 * @ingroup cxx11-backports
 * @ingroup string
 */
template<class Ch, class Tr = std::char_traits<Ch>, class Alloc = std::allocator<Ch>, class... Args>
std::basic_string<Ch,Tr,Alloc> 
to_basic_string(Args&&... args);

#endif // docs

#endif



|







 







<
|









1
2
3
4
5
6
7
8
9
10
11
..
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
#ifndef CXXOMFORT_IMPL_TO_BASIC_STRING_V_HPP
#define CXXOMFORT_IMPL_TO_BASIC_STRING_V_HPP
/**
 * @file
 * @brief Implements the variadic "to_basic_string" proposal in http://open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0117r0.html .
 *
 * 
 * Interfaces defined in this file:
 * 
 * In namespace cxxomfort::string:
 * 
................................................................................
#endif

#if defined(DOXYGEN_DOC)

/**
 * @brief Provides a string expression of its arguments.
 * @ingroup independent-utilities

 * @ref cxx11-backports
 * @ingroup string
 */
template<class Ch, class Tr = std::char_traits<Ch>, class Alloc = std::allocator<Ch>, class... Args>
std::basic_string<Ch,Tr,Alloc> 
to_basic_string(Args&&... args);

#endif // docs

#endif

Changes to cxxomfort/cxxomfort/impl/tuple_call.hpp.

1
2
3

4
5
6
7
8
9
10
..
14
15
16
17
18
19
20


21
22
23
24
25
26
27
..
49
50
51
52
53
54
55
56
57


58
59
60
61
62
63
64
#ifndef CXXOMFORT_IMPL_tuple_visit_HPP
#define CXXOMFORT_IMPL_tuple_visit_HPP
/*

 * Support for tuple_visit / tuple_foreach
 */

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

/*
 * returns 1 + the index of the first element of tt
 * for which p(get<>...) returns true
 */
template <typename P, typename Tuple>
int tuple_if (P p, Tuple const& tt) {


    return 0;
}

namespace detail {

template <typename F, typename Tuple, int I= 0, int S = std::tuple_size< typename std::remove_const<Tuple>::type >::value>
struct tuple_visit_each_t {
................................................................................

    private:
    tuple_visit_each_t& operator= (tuple_visit_each_t const&);
};

} // detail

/*
 * Call function f for each member of tuple tt


 * Could also be called foreach_tuple
 */

template <typename F, typename Tuple> inline 
Tuple& tuple_visit (F f, Tuple& t) {
    detail::tuple_visit_each_t<F,Tuple>(f,t);
    return t;



>







 







>
>







 







|
|
>
>







1
2
3
4
5
6
7
8
9
10
11
..
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#ifndef CXXOMFORT_IMPL_tuple_visit_HPP
#define CXXOMFORT_IMPL_tuple_visit_HPP
/*
 * @file 
 * Support for tuple_visit / tuple_foreach
 */

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

/*
 * returns 1 + the index of the first element of tt
 * for which p(get<>...) returns true
 */
template <typename P, typename Tuple>
int tuple_if (P p, Tuple const& tt) {
    (void)p;
    (void)tt;
    return 0;
}

namespace detail {

template <typename F, typename Tuple, int I= 0, int S = std::tuple_size< typename std::remove_const<Tuple>::type >::value>
struct tuple_visit_each_t {
................................................................................

    private:
    tuple_visit_each_t& operator= (tuple_visit_each_t const&);
};

} // detail

/**
 * @brief Call function f for each member of tuple tt
 * @ingroup independent-features
 * 
 * Could also be called foreach_tuple
 */

template <typename F, typename Tuple> inline 
Tuple& tuple_visit (F f, Tuple& t) {
    detail::tuple_visit_each_t<F,Tuple>(f,t);
    return t;

Changes to cxxomfort/cxxomfort/impl/unique_ptr.hpp.

Changes to cxxomfort/cxxomfort/library.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
..
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





























#ifndef CXXOMFORT_LIBRARY_HPP
#define CXXOMFORT_LIBRARY_HPP
/**
 * @file library.hpp
 * @brief Implementations and additions proper to the cxxomfort library.
 * @addtogroup independent-features
 * 
 *
 * Implementations included from here:
 * 
 * * CXXO_FOREACH
 * * i12n
 * * fixed_vector
 * * pair03
 * * type_name
 * 
 */

#include <cxxomfort/utility.hpp>

// extra algorithm variants (find_last_if, count_while, etc)
#include "library/algorithmfn.hpp"
// for (x:range) emulation
#include "library/foreach.hpp"
................................................................................
#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"
// typesafe_enum
#include "library/typesafe_enum.hpp"

/*
 * is_pair
 */
namespace cxxomfort {


}


#endif

/**
 * @page independent-features

 * 
 * The set of utilities and features specific to cxxomfort, themselves not 
 * part or backport of any Standard feature.
 * 
 */































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







 







>
>













<
<
<

>
|


<
<
<

|
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2















3
4
5
6
7
8
9
..
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
#ifndef CXXOMFORT_LIBRARY_HPP
#define CXXOMFORT_LIBRARY_HPP
















#include <cxxomfort/utility.hpp>

// extra algorithm variants (find_last_if, count_while, etc)
#include "library/algorithmfn.hpp"
// for (x:range) emulation
#include "library/foreach.hpp"
................................................................................
#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"
// numeric-related stuff
#include "library/numericfn.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"
// typesafe_enum
#include "library/typesafe_enum.hpp"




namespace cxxomfort {
namespace library {
}
}




/**
 * @defgroup independent-features "Library Features"
 * @brief cxxomfort's own features and additions
 * 
 * The set of utilities and features specific to cxxomfort, themselves not 
 * part or backport of any Standard feature.
 * 
 */

/**
 * @page cxxo:sup Library Supplements
 * @brief Implementations and additions proper to the cxxomfort library.
 * @addtogroup independent-features
 * 
 * The @b cxxomfort library does not only implement backports to C++ features; it also brings its own set of features to supplement various functionality that, for example, can not be backported to previous version in a meaningful fashion. 
 * 
 * Including the <code><cxxomfort/library.hpp></code> header and invoking the <code>cxxomfort::</code> namespace makes these features available.
 * 
 * Implementations included from here:
 * 
 * * @subpage cxxo:sup:algorithm "Supplements for <algorithm>"
 * * @subpage cxxo:sup:functional "Supplements for <functional>"
 * * @subpage cxxo:sup:random "Supplements for <random>"
 * * @subpage cxxo:sup:string "Supplements for <string>"
 * * @subpage cxxo:sup:tuple "Supplements for <tuple>"
 * 
 * * @subpage cxxo:FOREACH "FOREACH (foreach loop)"
 * * @subpage cxxo:i12n "I12N (Container Initialization)"
 * * @subpage cxxo:fixed_vector "Fixed vector"
 * * @subpage cxxo:fundamental "Fundamental"
 * 
 * * @ref cxxo:pair03 "Pair"
 * * @ref cxxo:clstring "clString"
 * * @ref cxxo:type_name "type_name"
 * 
 */
#endif

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

1
2
3
4
5
6
7






8

9
10
11
12
13
14
15
..
30
31
32
33
34
35
36






37


38
39
40
41
42
43
44
..
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
..
95
96
97
98
99
100
101




102


















103
104
105

























106
#ifndef CXXOMFORT_CXXO_ALGORITHMFN_HPP
#define CXXOMFORT_CXXO_ALGORITHMFN_HPP
#include <cxxomfort/config.hpp>
#include <cxxomfort/base.hpp>
#include <algorithm>
#include <iterator>







namespace cxxomfort {

namespace algorithm {

namespace detail {

template<class It, class Pred>
It find_last_if (It ini, It fin, Pred f, std::forward_iterator_tag) {
    using namespace std;
................................................................................
    }
    return ret;
}

} // .detail::

/**






 * @brief Finds the last item that fulfills @c f .


 */
template <typename Iter, typename Pred>
Iter find_last_if (Iter ini, Iter fin, Pred f) {
    typedef const typename std::iterator_traits<Iter>::iterator_category cat;
    return detail::find_last_if(ini, fin, f, cat());
}

................................................................................
    typename std::iterator_traits<InputIterator>::difference_type ret = 0;
    while (first!=last && pred(*first)) {
        ++ret;
        ++first;
    }
    return ret;
}



/**
 * @brief Transform elements in the range in-place via the transformation @a tf .

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















//! transform elements up to n times


template <typename IIterator, typename OIterator, typename TF, typename Integer>
inline OIterator transform_n (IIterator ini, Integer n, OIterator dest, TF tf) {
    for (Integer i(0); i < n; ++i) { *dest= tf(*ini); }
    return dest;
}


................................................................................
    for (; ini != fin; ++ini) {
        v[*ini]++;
    }
    return ini;
}

























} // .algorithm::
}


























#endif






|
>
>
>
>
>
>
|
>







 







>
>
>
>
>
>
|
>
>







 







>
>



>









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







 







>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
..
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
...
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
#ifndef CXXOMFORT_CXXO_ALGORITHMFN_HPP
#define CXXOMFORT_CXXO_ALGORITHMFN_HPP
#include <cxxomfort/config.hpp>
#include <cxxomfort/base.hpp>
#include <algorithm>
#include <iterator>

/**
 * @file
 * @brief cxxomfort's algorithm-related functions
 */


namespace cxxomfort {
//! Namespace for the objects in @ref cxxo:sup:algorithm .
namespace algorithm {

namespace detail {

template<class It, class Pred>
It find_last_if (It ini, It fin, Pred f, std::forward_iterator_tag) {
    using namespace std;
................................................................................
    }
    return ret;
}

} // .detail::

/**
 * @ingroup cxxo:sup:algorithm
 * @ref cxxo:sup:algorithm
 * @{
 */

/**
 * @brief Finds the latest item in a sequence that fulfills @c f .
 * @param ini,fin Delimiters to the sequence to be examined.
 * @return An iterator pointing to the latest item in <code>[ini,fin)</code> that fulfills @c f .
 */
template <typename Iter, typename Pred>
Iter find_last_if (Iter ini, Iter fin, Pred f) {
    typedef const typename std::iterator_traits<Iter>::iterator_category cat;
    return detail::find_last_if(ini, fin, f, cat());
}

................................................................................
    typename std::iterator_traits<InputIterator>::difference_type ret = 0;
    while (first!=last && pred(*first)) {
        ++ret;
        ++first;
    }
    return ret;
}



/**
 * @brief Transform elements in the range in-place via the transformation @a tf .
 * @param tf A transformation of the form <code>TF(*FIter) -> *FIter</code>.
 */
template <typename FIter, typename TF>
FIter transform_inplace (FIter ini, FIter fin, TF tf) {
    for (; ini != fin; ++ini) {
        *ini= tf(*ini);
    }
    return ini;
}

/**
 * @brief Transform elements in the range conditionally.
 * @param tf A transformation of the form <code>TF(*FIter) -> *FIter</code>.
 * @param f a predicate to decide if the elements need transformation.
 */
template <typename FIter, typename TF, typename P>
FIter transform_inplace_if (FIter ini, FIter fin, TF tf, P p) {
    for (; ini != fin; ++ini) {
        if (p(*ini)) *ini= tf(*ini);
    }
    return ini;
}

/**
 * @brief Transform elements up to n times
 * @param tf A transformation of the form <code>TF(*FIter) -> *FIter</code>.
 */
template <typename IIterator, typename OIterator, typename TF, typename Integer>
inline OIterator transform_n (IIterator ini, Integer n, OIterator dest, TF tf) {
    for (Integer i(0); i < n; ++i) { *dest= tf(*ini); }
    return dest;
}


................................................................................
    for (; ini != fin; ++ini) {
        v[*ini]++;
    }
    return ini;
}


/*
 * fwsort
 * sort but for non-random access iterators. Requires fw-iterators.
 */

/*
template <typename FwIter, typename Less>
void fwsort (FwIter ini, FwIter fin, Less l) {
    using namespace std;
    if (ini==fin) return;
    FwIter p= ini;
    for (; p != fin; ++p) {
        FwIter m= min_element(p, fin, l);
        if (!(p==m)) iter_swap(p,m);
    }
}
*/


/**
 * @}
 */

} // .algorithm::
}

/**
 * @page cxxo:sup:algorithm
 * 
 * This file provides supplementary features for the set of 
 * algorithms present in <code><algorithm></code> that are 
 * specific to cxxomfort, as well as functions that complete the 
 * family of <code>_n</code> functions such as <code>transform_n</code>.
 * 
 * Interfaces defined in this file:
 * 
 * * @ref count_while
 * * @ref find_inversion
 * * @ref find_last_if
 * * @ref transform_inplace
 * * @ref transform_inplace_if
 * * @ref transform_n
 * * @ref count_frequencies_map
 * * @ref count_frequencies
 * * @ref relative_search
 * 
 * 
 * All interfaces are defined in the namespace <code>cxxomfort::algorithm::</code>.
 * 
 */

#endif

Changes to cxxomfort/cxxomfort/library/fixed_vector.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
..
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
...
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
...
198
199
200
201
202
203
204

205
206
207
208
209
210
211
...
228
229
230
231
232
233
234

235
236
237
238
239
240
241
...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
#ifndef CXXOMFORT_IMPL_FIXED_VECTOR_HPP
#define CXXOMFORT_IMPL_FIXED_VECTOR_HPP
/**
 * @file fixed_vector.hpp
 * @brief Implementation of a fixed-size variant of vector<>.
 * @author Luis Machuca Bezzaza
 * @sa dynarray
 *
 */


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


namespace cxxomfort{

template <typename T, typename Alloc> class fixed_vector;

/**
 * @brief Dynamic array (aka fixed vector) container for C++.
 * @anchor fixed_vector

 * @ingroup independent-features
 *




 * A @c fixed_vector is a container of contiguous storage of elements
 * of type @e T.

 * It behaves much like a <code>vector<T></code> except there is no resize or
 * reserve support - the size of the container is fixed at construction time.

 *
 * Part of the spirit of this kind of "missing" container is what originated
 * n2648's "dynarray". However that proposal goes far beyond the mere
 * concept of a "fixed vector".
 *
 * An instance of fixed_vector<T> stores elements of type T.
 * The elements of a fixed_vector are stored contiguously, meaning that if d
 * is an fixed_vector<T> then it obeys the identity
 * &a[n] == &a[0] + n for all 0 <= n < N."
 *
 * A @c fixed_vector  presents the some of the same interface convenients as
 * other standard containers:
 *
 * * except where specified, no members throw
 * * copy constructor and iterator constructor

 * * indexed accesors (@c at() and @c operator[] ) with usual semantics
 * * iteration member accesors and types
 * * nonmember equality comparison operators



 * 
 * The following features are missing at present:
 * 
 * * Allocator support.
 * 
 *
 */
template <typename T, typename Alloc=std::allocator<T> > class fixed_vector {
    typedef fixed_vector<T>  this_type;
    private:
    typedef Alloc        alloc_t;
    typedef std::allocator_traits<Alloc>     alloc_traits;
................................................................................
    fixed_vector (std::initializer_list<T> const&) CXXO_NOEXCEPT;             ///< (7) initializer_list-ctor
#endif

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

    ~fixed_vector ();                                 ///< destructor




    fixed_vector& operator= (fixed_vector rhs);









    
    size_type       max_size () const CXXO_NOEXCEPT { return m_sz; }
    size_type       size () const CXXO_NOEXCEPT { return m_sz; } ///< size of container
    bool            empty () const CXXO_NOEXCEPT { return m_p == nullptr && m_sz == 0; } // nothrow

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

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

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


    const_reference front () const CXXO_NOEXCEPT { return m_p[0]; } // nothrow

    reference       front () CXXO_NOEXCEPT { return m_p[0]; } // nothrow

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

    reference       back  () CXXO_NOEXCEPT{ return m_p[m_sz-1]; } // nothrow

    //@ Iterator to the beginning
    const_iterator  cbegin () const CXXO_NOEXCEPT { return m_p; } // nothrow
    //@ Iterator to the beginning
    const_iterator  begin  () const CXXO_NOEXCEPT { return cbegin(); } // nothrow
    //@ @overloads begin
    iterator        begin  () CXXO_NOEXCEPT { return m_p; } // nothrow

    const_iterator  cend   () const CXXO_NOEXCEPT { return m_p+m_sz; } // nothrow
    //@ Iterador apuntando al final+1.

    const_iterator  end    () const CXXO_NOEXCEPT { return cend(); } // nothrow
    //* @overloads end
    iterator        end    () CXXO_NOEXCEPT { return m_p+m_sz; } // nothrow


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

    reverse_iterator     rbegin () CXXO_NOEXCEPT {
        return reverse_iterator(this->end());
    }

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

    reverse_iterator     rend () CXXO_NOEXCEPT {
        return reverse_iterator(this->begin());
    }

    //! fill with copies of value @em v
    void fill (T const& v) {
        for (iterator i= this->begin(); i != this->end(); ++i) {*i= v;}
................................................................................
    //! swap
    void swap (fixed_vector<T,Alloc> & rhs) {
        std::swap(this->m_p, rhs.m_p);
        std::swap(this->m_sz, rhs.m_sz);
        //std::swap(this->m_a, rhs.m_a);
    }

    //! assign copy of another vector
    fixed_vector& assign (fixed_vector rhs) CXXO_NOEXCEPT {
        this->swap(rhs);
        return *this;
    }

    private:
    size_t m_sz;
    T* m_p;
    //Alloc m_a;

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

    }

};

//
// default constructor
//
................................................................................
//
// copy constructor
//
template <typename T, typename Alloc>
fixed_vector<T,Alloc>::fixed_vector (fixed_vector const &V) // strong_throw
: m_p ( alloc(V.m_sz) ), m_sz(V.m_sz) {
    size_t i;

    try {
        using namespace std;
        uninitialized_copy(V.begin(), V.end(), this->begin());
    } catch(...) {

        delete[] m_p; m_p= nullptr;
        throw; // rethrow
................................................................................
}

template <typename T, typename Alloc>
fixed_vector<T,Alloc>::fixed_vector (size_type N, T const& v) // strong_throw
: m_sz(N), m_p ( alloc(N) ) {
    using namespace std;
    size_t i= 0;

    try {
        uninitialized_fill(m_p, m_p+m_sz, v);
    } catch(...) {
        delete[] m_p; m_p= nullptr;
        throw; // rethrow
    }//~catch
}
................................................................................
        throw; // rethrow
    }
}

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

// Move constructor
template <typename T, typename Alloc>



|
|
|
<
|
|
<







 







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






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




|







 







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





|



|




|





|



|




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



>



>



>







 







|
|
|
<
|











>







 







>







 







>







 







|







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
..
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
...
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
...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
...
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
...
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
#ifndef CXXOMFORT_IMPL_FIXED_VECTOR_HPP
#define CXXOMFORT_IMPL_FIXED_VECTOR_HPP
/**
 * @file
 * @brief Implementation of a fixed-size variant of vector<>.
 * @author Luis Machuca Bezzaza

 *
 */


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


namespace cxxomfort{

template <typename T, typename Alloc> class fixed_vector;

/**

 * @page library:fixed_vector
 * @brief Fixed vector (vector with size fixed at construction) container for C++.
 * @ingroup independent-features
 */


/**
 *
 * A @c fixed_vector is a container for continuous and fixed-size storage of elements fo type @a T .

 * 
 * It behaves much like a <code>vector<T><T></code> except there is no resize or
 * reserve support, as the size of the container is fixed at construction time; 
 * consequently, the semantics of insert and erase also change.
 *
 * Part of the spirit of this kind of "missing" container is what originated
 * n2648's "dynarray". However that proposal goes far beyond the mere
 * concept of a "fixed vector".
 *
 * An instance of fixed_vector<T> stores elements of type T.
 * The elements of a fixed_vector are stored contiguously, meaning that if @a a 
 * is an fixed_vector<T> then it obeys the identity
 * <code>&a[n] == &a[0] + n</code> for all 0 <= n < N."
 *
 * A @c fixed_vector  presents the some of the same interface convenients as
 * other standard containers, changing only some details:
 *

 * * copy constructor and iterator constructor.
 * * @c move  capability (including in C++03).
 * * indexed accesors (@c at() and @c operator[] ) with usual semantics.
 * * iteration member accesors and types.
 * * equality comparison operators.
 * * except where specified, no members throw.
 * * only one version of @c insert exists, which behaves similarly to @c at .
 * * only one version of @c erase exists, which behaves similarly to @c at .
 * 
 * The following features are missing at present:
 * 
 * * Allocator support.
 * * emplace inserts.
 *
 */
template <typename T, typename Alloc=std::allocator<T> > class fixed_vector {
    typedef fixed_vector<T>  this_type;
    private:
    typedef Alloc        alloc_t;
    typedef std::allocator_traits<Alloc>     alloc_traits;
................................................................................
    fixed_vector (std::initializer_list<T> const&) CXXO_NOEXCEPT;             ///< (7) initializer_list-ctor
#endif

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

    ~fixed_vector ();                                 ///< destructor

    // Assignment
    ////////
    
    fixed_vector& operator= (fixed_vector rhs);

    //! assign copy of another vector
    fixed_vector& assign (fixed_vector rhs) CXXO_NOEXCEPT {
        this->swap(rhs);
        return *this;
    }

    // Information
    ////////
    
    size_type       max_size () const CXXO_NOEXCEPT { return m_sz; }
    size_type       size () const CXXO_NOEXCEPT { return m_sz; } ///< size of container
    bool            empty () const CXXO_NOEXCEPT { return m_p == nullptr && m_sz == 0; } // nothrow

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

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

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

    //! access to front
    const_reference front () const CXXO_NOEXCEPT { return m_p[0]; } // nothrow
    //! @overload front
    reference       front () CXXO_NOEXCEPT { return m_p[0]; } // nothrow
    //! access to back
    const_reference back  () const CXXO_NOEXCEPT { return m_p[m_sz-1]; } // nothrow
    //! @overload back
    reference       back  () CXXO_NOEXCEPT{ return m_p[m_sz-1]; } // nothrow

    //! Iterator to the beginning
    const_iterator  cbegin () const CXXO_NOEXCEPT { return m_p; } // nothrow
    //! Iterator to the beginning
    const_iterator  begin  () const CXXO_NOEXCEPT { return cbegin(); } // nothrow
    //! @overload begin
    iterator        begin  () CXXO_NOEXCEPT { return m_p; } // nothrow
    //! Iterator to the end
    const_iterator  cend   () const CXXO_NOEXCEPT { return m_p+m_sz; } // nothrow

    //! Iterador to the end
    const_iterator  end    () const CXXO_NOEXCEPT { return cend(); } // nothrow
    //! @overload end
    iterator        end    () CXXO_NOEXCEPT { return m_p+m_sz; } // nothrow

    //! Reverse iterator access to the end
    const_reverse_iterator    rbegin () const CXXO_NOEXCEPT {
        return const_reverse_iterator(this->end());
    }
    //! @overload rbegin
    reverse_iterator     rbegin () CXXO_NOEXCEPT {
        return reverse_iterator(this->end());
    }
    //! Reverse iterator access to the beginning
    const_reverse_iterator     rend () const CXXO_NOEXCEPT {
        return const_reverse_iterator(this->begin());
    }
    //! @overload rend
    reverse_iterator     rend () CXXO_NOEXCEPT {
        return reverse_iterator(this->begin());
    }

    //! fill with copies of value @em v
    void fill (T const& v) {
        for (iterator i= this->begin(); i != this->end(); ++i) {*i= v;}
................................................................................
    //! swap
    void swap (fixed_vector<T,Alloc> & rhs) {
        std::swap(this->m_p, rhs.m_p);
        std::swap(this->m_sz, rhs.m_sz);
        //std::swap(this->m_a, rhs.m_a);
    }

// unimplemented
#if 0
#endif



    private:
    size_t m_sz;
    T* m_p;
    //Alloc m_a;

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

};

//
// default constructor
//
................................................................................
//
// copy constructor
//
template <typename T, typename Alloc>
fixed_vector<T,Alloc>::fixed_vector (fixed_vector const &V) // strong_throw
: m_p ( alloc(V.m_sz) ), m_sz(V.m_sz) {
    size_t i;
    i= 0;
    try {
        using namespace std;
        uninitialized_copy(V.begin(), V.end(), this->begin());
    } catch(...) {

        delete[] m_p; m_p= nullptr;
        throw; // rethrow
................................................................................
}

template <typename T, typename Alloc>
fixed_vector<T,Alloc>::fixed_vector (size_type N, T const& v) // strong_throw
: m_sz(N), m_p ( alloc(N) ) {
    using namespace std;
    size_t i= 0;
    (void)i;
    try {
        uninitialized_fill(m_p, m_p+m_sz, v);
    } catch(...) {
        delete[] m_p; m_p= nullptr;
        throw; // rethrow
    }//~catch
}
................................................................................
        throw; // rethrow
    }
}

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

// Move constructor
template <typename T, typename Alloc>

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

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef CXXOMFORT_FOREACH_HPP
#define CXXOMFORT_FOREACH_HPP

/**
 * @file cxxomfort/extras/foreach.hpp
 * @brief Implements backwards-compatible range-for functionality
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces implemented in this file:
 *
 * * CXXO_FOREACH
 *




|







1
2
3
4
5
6
7
8
9
10
11
12
#ifndef CXXOMFORT_FOREACH_HPP
#define CXXOMFORT_FOREACH_HPP

/**
 * @file
 * @brief Implements backwards-compatible range-for functionality
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces implemented in this file:
 *
 * * CXXO_FOREACH
 *

Changes to cxxomfort/cxxomfort/library/functionalfn.hpp.

4
5
6
7
8
9
10

11
12
13
14
15
16











17
#include <cxxomfort/base.hpp>
#include <functional>
#include <iterator>

#include "operatorit.hpp" // supplement operator functors

namespace cxxomfort {

namespace functional {


} // .functional:
}












#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
#include <cxxomfort/base.hpp>
#include <functional>
#include <iterator>

#include "operatorit.hpp" // supplement operator functors

namespace cxxomfort {
//! Namespace for the objects in @ref cxxo:sup:functional .
namespace functional {


} // .functional:
}

/**
 * @page cxxo:sup:functional "Supplements to <functional>"
 * @brief Offers cxxomfort-specific supplements to <code><functional></code> features.
 * 
 * This section offers a number of alternatives and supplements to features found in 
 * <code><functional></code> such as function objects to complete various tasks, 
 * a function-like reference wrapper, and 
 * function objects that complement the <code>plus</code> family.
 * 
 */

#endif

Changes to cxxomfort/cxxomfort/library/i12n.hpp.

1
2
3
4
5
6
7

8
9




10
11
12
13
14
































15
16
17
18
19
20
21
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77


















































78
#ifndef CXXOMFORT_IMPL_I12N_HPP
#define CXXOMFORT_IMPL_I12N_HPP
#include <cxxomfort/config.hpp>
/**
 * @file cxxomfort/impl/i12n.hpp
 * @brief Implements <code>= {...}</code>-like initialization semantics for containers.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>

 * @ingroup independent-features
 * 




 * Defines the dual macros @c CXXO_I12N_BEG and @c CXXO_I12N_END 
 * that provide initialization semantics for containers similar to the 
 * initializer_list constructors in C++11.
 * 
 * For documentation see @link Features/I12N @endlink .
































**/

#if (CXXOMFORT_CXX_STD < 2011)

    #if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1)
    #pragma message CXXO_NOTICE ("enabled container initialization helper")
    #endif
................................................................................
#define CXXO_I12N_END(Type,Name) ; Type Name ((Name##0init), cxxomfort::i12n_detail::I12N_for< Name##0ncv >(Name##0init).ender)

// If compiler supports variadic macros, this can be used:
#if (CXXO_COMPILER_SUPPORT_va_args==1 )
#define CXXO_I12N_SEQ(Type,Name,...) CXXO_I12N_BEG(Type,Name) =  __VA_ARGS__ CXXO_I12N_END(Type,Name)
#endif

/*
 * Mode of use:

vector<int> vn CXXO_SQ_BEG(vn) = {1, 2, 3, 4} CXXO_SQ_END(vn);

 *
 */
#else
//! Begins a sequence initialization construct
    #define CXXO_I12N_BEG(Type,Name) Type  Name
//! Finishes a sequence initialization construct
    #define CXXO_I12N_END(Type,Name)
//! Variadic sequence initialization construct
    #define CXXO_I12N_SEQ(Type,Name,...)  Type Name ({__VA_ARGS__});

#endif // c++11



















































#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
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
..
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
#ifndef CXXOMFORT_IMPL_I12N_HPP
#define CXXOMFORT_IMPL_I12N_HPP
#include <cxxomfort/config.hpp>
/**
 * @file

 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 * @brief Implements <code>= {...}</code>-like initialization semantics for containers.
 */


/**
 * @page library:i12n "I12N (initialization)"
 * 
 * Defines the dual macros @c CXXO_I12N_BEG and @c CXXO_I12N_END 
 * that provide initialization semantics for containers similar to the 
 * initializer_list constructors in C++11.
 * 

 * Interfaces defined:
 * 
 * * @ref CXXO_I12N_BEG
 * * @ref CXXO_I12N_END
 * * @ref CXXO_I12N_SEQ
 * 
 * Sample usage:
 * @code

CXXO_I12N_BEG( vector<int> , vn );
{1, 2, 3, 4, 5, 6, 7}
CXXO_I12N_END( vector<int> , vn );

CXXO_I12N_SEQ( vector<int> , vs , 
 {1, 2, 3, 4, 5, 6, 7}
 );


 * @endcode
 * 
 * @b Requirements:
 * 
 * Requirements:
 * 
 * * Containers using this utility must provide an adequate @c value_type member.
 * * Containers using this utility must support iterator-range constructors.
 * * In C++03 mode, data types using this utility must be copyable.
 * 
 * Because of these requirements and other reasons intrinsic to its structure 
 * as a pseudo-container different from the C++ template sequences, 
 * i12n can not work with <code>std::array<...></code>.
 * 
**/

#if (CXXOMFORT_CXX_STD < 2011)

    #if defined(CXXOMFORT_NOTICES) && (CXXOMFORT_NOTICES > 1)
    #pragma message CXXO_NOTICE ("enabled container initialization helper")
    #endif
................................................................................
#define CXXO_I12N_END(Type,Name) ; Type Name ((Name##0init), cxxomfort::i12n_detail::I12N_for< Name##0ncv >(Name##0init).ender)

// If compiler supports variadic macros, this can be used:
#if (CXXO_COMPILER_SUPPORT_va_args==1 )
#define CXXO_I12N_SEQ(Type,Name,...) CXXO_I12N_BEG(Type,Name) =  __VA_ARGS__ CXXO_I12N_END(Type,Name)
#endif








#else
// Begins a sequence initialization construct
    #define CXXO_I12N_BEG(Type,Name) Type  Name
// Finishes a sequence initialization construct
    #define CXXO_I12N_END(Type,Name)
// Variadic sequence initialization construct
    #define CXXO_I12N_SEQ(Type,Name,...)  Type Name ({__VA_ARGS__});

#endif // c++11

#ifdef DOXYGEN_DOC

/**
 * @addtogroup independent-features
 * @{
 */

/**
 * @def CXXO_I12N_BEG(SequenceT,Var) 
 * @brief Begins an initialization sequence.
 * @param SequenceT the type of the desired object.
 * @param Var the name of the desired object.
 * 
 * See usage case.
 * 
 */
#define CXXO_I12N_BEG(SequenceT, Var) implementation_defined

/**
 * @def CXXO_I12N_END(SequenceT,Var) 
 * @brief Finishes an initialization sequence.
 * @param SequenceT the type of the desired object.
 * @param Var the name of the desired object.
 * 
 * See usage case.
 * 
 */
#define CXXO_I12N_END(SequenceT, Var) implementation_defined


/**
 * @def CXXO_I12N_SEQ(SequenceT,Var,List...) 
 * @brief Constructs a sequence-like object.
 * @param Type the type of the desired object.
 * @param Var the name of the desired object.
 * @param List a brace-enclosed listing of elements for the object.
 * 
 * This macro wraps the usage of CXXO_I12_BEG and CXXO_I12N_END in a singular "oneliner" for compilers that have support for variadic macros.
 * 
 * 
 */
#define CXXO_I12N_SEQ(SequenceT, Var, {List...}) implementation_defined


/**
 * @}
 */

#endif // DOFS

#endif

Changes to cxxomfort/cxxomfort/library/iteratorfn.hpp.

1
2
3
4
5
6
7
8




9

10
11
12
13
14
15
16
17
18
19
20
21
..
69
70
71
72
73
74
75
76






77
#ifndef CXXOMFORT_CXXO_ITERATORFN_HPP
#define CXXOMFORT_CXXO_ITERATORFN_HPP
#include <cxxomfort/config.hpp>
#include <cxxomfort/base.hpp>
#include <iterator>
#include <functional>
//#include <type_traits>





namespace cxxomfort {

namespace iterator {

/**
 * fake_iterator
 * iterates over nothing, it just stays "pointing" to the same place
 */
template <typename T>
struct fake_iterator {
    typedef std::reference_wrapper<T const> V;
    typedef std::bidirectional_iterator_tag iterator_category;
    typedef T value_type;
    typedef size_t difference_type;
................................................................................
struct function_iterator {
};

// iterator
}
// cxxomfort
}







#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
..
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#ifndef CXXOMFORT_CXXO_ITERATORFN_HPP
#define CXXOMFORT_CXXO_ITERATORFN_HPP
#include <cxxomfort/config.hpp>
#include <cxxomfort/base.hpp>
#include <iterator>
#include <functional>
//#include <type_traits>

/**
 * @file
 */

namespace cxxomfort {

namespace iterator {

/**

 * @brief iterates over nothing, it just stays "pointing" to the same place
 */
template <typename T>
struct fake_iterator {
    typedef std::reference_wrapper<T const> V;
    typedef std::bidirectional_iterator_tag iterator_category;
    typedef T value_type;
    typedef size_t difference_type;
................................................................................
struct function_iterator {
};

// iterator
}
// cxxomfort
}

/**
 * @page cxxo:sup:iterator
 * 
 * Supplements to the utilities found in <code><iterator></code>.
 */

#endif

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

Added cxxomfort/cxxomfort/library/numericfn.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
#ifndef CXXOMFORT_CXXO_NUMERICFN_HPP
#define CXXOMFORT_CXXO_NUMERICFN_HPP
#include <cxxomfort/config.hpp>
#include <cxxomfort/base.hpp>
#include <numeric>
#include <iterator>

/**
 * @file
 * @brief cxxomfort's numeric-related functions
 */


namespace cxxomfort {
//! Namespace for the objects in @ref cxxo:sup:algorithm .
namespace numeric {

template <typename It, typename T, typename F>
T accumulate_right (It ini, It fin, T v0, F f) {
    for (; ini != fin; ++ini) {
        v0 = f(*ini, v0);
    }    
    return v0;
}

template <typename It, typename T>
T accumulate_right (It ini, It fin, T v0) {
    for (; ini != fin; ++ini) {
        v0 = *ini + v0;
    }    
    return v0;
}

template <typename I, I i1, I i2>
struct static_gcd_typed {
    static const I value= (i2==0) ? i1 : static_gcd_typed<I, i2, i1 % i2>::value;
};


template <unsigned i1, unsigned i2>
struct static_gcd_impl {
    static const unsigned value= (i2==0U) ? i1 : static_gcd_impl<i2, i1 % i2>::value ;
};

/*
template <unsigned i1>
struct static_gcd_impl<i1,0U> {
    static const unsigned value= i1 ;
};
*/

template <unsigned i1, unsigned i2>
struct static_gcd {
    //static const unsigned value= static_gcd_impl<i1,i2>::value;
    static const unsigned value= (i2==0U) ? i1 : static_gcd<i2, i1 % i2>::value ;
};

template <unsigned i1>
struct static_gcd<i1,0> {
    //static const unsigned value= static_gcd_impl<i1,i2>::value;
    static const unsigned value= i1;
};

template <unsigned i1, unsigned i2>
struct static_lcm {
    static const unsigned value= i1 / static_gcd<i1,i2>::value * i2;
};

// return (b== 0) ? a : gcd(b, a % b);

} // numeric::
}


#endif

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
..
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
..
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
#ifndef CXXOMFORT_CXXO_OPERATORIT_HPP
#define CXXOMFORT_CXXO_OPERATORIT_HPP

/**
 * @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; }

};


................................................................................
    typedef It result_type;            \
    inline It& operator() (It& l, Ot const& r) const {   \
        return l Sym r;       \
    }                         \
};                            \


/**
 * @ingroup independent-features
 * @{
 */

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





|

<







 







>
>
>
>
>
>


>
>
>
>
>
>
>
>








>





>
>
>








>







 







<
<
<
<
<







>
>
>




|
<
<




1
2
3
4
5
6

7
8
9
10
11
12
13
..
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
..
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
#ifndef CXXOMFORT_CXXO_OPERATORIT_HPP
#define CXXOMFORT_CXXO_OPERATORIT_HPP

/**
 * @file 
 * @brief Implementations and additions of ${operator}_it functoids similar to <functional>.

 * 
 * 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 
 * @brief Supplements to functionality in <code><functional></code>.
 * @ingroup cxxo:sup:functional
 */
namespace functional {

/**
 * @ingroup cxxo:sup:functional 
 * @{
 */

/**
 * @brief Functoid that wraps <code>++t</code> for a given @a T .
 */
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; }
};

//! Heterogeneous (deduced) wrapper for @ref preincrement .
template<> struct preincrement<void> {
    template <typename T>
    T& operator() (T& t) const { ++t; return t; }
};

/**
 * @brief Functoid that wraps <code>--t</code> for a given @a 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; }
};

//! Heterogeneous (deduced) wrapper version of predecrement.
template<> struct predecrement<void> {
    template <typename T>
    T& operator() (T& t) { --t; return t; }

};


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

/**
 * @}
 */

} // functional


} // cxxomfort

#endif

Changes to cxxomfort/cxxomfort/library/pair03.hpp.

Changes to cxxomfort/cxxomfort/library/stringfn.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
..
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
#ifndef CXXOMFORT_CXXO_STRINGFN_HPP
#define CXXOMFORT_CXXO_STRINGFN_HPP

/**
 * @file stringfn.hpp
 * @brief cxxomfort's string-related functions
 * @ingroup independent-features
 * 
 * C++'s string public interface kinda sucks so we 
 * add some functions to complement it here. 
 * While they are intended to work with std::string, 
 * they should be able to work well with any char-type.
 * 
 * Interfaces defined in this file:
 * 
 * * join
 * * (TBA) split
 * * (TBA) substr
 * * l_trim, r_trim
 * * trim
 * 
 */

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

#include "../impl/to_basic_string_variadic.hpp"



























namespace cxxomfort {





namespace string {


/**

























































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


 */
template <typename String, typename Iterator1, typename Iterator2>
String join (String const& sep, Iterator1 ini, Iterator2 fin) {
    String ret;
    if (ini != fin) {
        std::stringstream ss; //<- needs to change to be generic
        ss<< *ini++;
................................................................................
            ss<< sep<< *ini;
        }
        ret= ss.str();
    }
    return ret;
}


//! @overloads join
template <typename Iterator1, typename Iterator2> inline 
std::string join (std::string const& sep, Iterator1 ini, Iterator2 fin) {
    return join<std::string>(sep,ini,fin);
}

















































template <typename String, typename Pred>
void l_trim (String& s, Pred p) {
    using namespace std;
    // we find L = first position in s where p(L) is false
    // we use string's erase function (or just a copy constructor)
    typename String::iterator L = find_if_not(begin(s), end(s), p);
    if (L == end(s)) return;
    s= String(L, end(s));
}








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






}
} // cxxomfort


#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
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
...
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
#ifndef CXXOMFORT_CXXO_STRINGFN_HPP
#define CXXOMFORT_CXXO_STRINGFN_HPP

/**
 * @file stringfn.hpp
 * @brief cxxomfort's string-related functions

 */















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

#include "../impl/to_basic_string_variadic.hpp"

/**
 * @page cxxo:sup:string
 * 
 * This file provides supplementary features to the ones
 * present in <code><string></code> that are 
 * specific to cxxomfort.
 * 
 * Interfaces defined in this file:
 * 
 * * @ref cxxomfrt::string::chr
 * * @ref cxxomfort::string::utf8chr
 * * @ref codepoint
 * * @ref join
 * * @ref split_to
 * * @ref split_to_n
 * * @ref explode
 * * @ref l_trim
 * * @ref r_trim
 * * @ref trim
 * 
 * 
 * All interfaces are defined in the namespace <code>cxxomfort::algorithm::</code>.
 * 
 */


namespace cxxomfort {

/**
 * @addtogroup cxxo:sup:string
 * @{
 */
namespace string {


/**
 * @brief Returns a string representation of an ASCII ordinal.
 * @return a 1-character string of type String.
 */
template <typename String>
String chr (uint16_t ascii) {
    if (ascii >= 0x100) throw std::out_of_range(
        cxxomfort::string::to_string("cxxomfort::string::chr: ascii(", static_cast<uint16_t>(ascii), ") out of range")
    );
    char q[]= "0";
    q[0]= ascii;
    return q;
}


// specialization for std::string and std::wstring using their special constructors.
static inline std::string chr (uint16_t ascii) {
    if (ascii >= 0x100) throw std::out_of_range(
        cxxomfort::string::to_string("cxxomfort::string::chr: ascii(", static_cast<uint16_t>(ascii), ") out of range")
    );
    return std::string(1, static_cast<char>(ascii));
}

static inline std::wstring wchr (uint16_t ascii) {
    if (ascii >= 0x100) throw std::out_of_range(
        cxxomfort::string::to_string("cxxomfort::string::chr: ascii(", static_cast<uint16_t>(ascii), ") out of range")
    );
    return std::wstring(1, static_cast<wchar_t>(ascii));
}

static std::string utf8chr (unsigned long cp) {
	using namespace std;
	char chu[5] = {0x00, 0x00, 0x00, 0x00, 0x00};
	if (false) {
	} else if (cp <= 0x7f) {
		chu[0] = cp;
	} else if (cp <= 0x07ff)  {
        chu[0]= (cp>>6)+192;
        chu[1]= (cp&63)+128;
        }
    else if (cp <= 0xffff) {
		chu[0]= (uint8_t)(cp>>12)+224;
		chu[1]= ((cp>>6)&63)+128;
		chu[2]= (cp&63)+128 ;
	}
	else if (cp <= 0x1fffff) {
		chu[0]= (cp>>18)+240;
		chu[1]= ((cp>>12)&63)+128;
		chu[2]= ((cp>>6)&63)+128;
		chu[3]= (cp&63)+128;
	}
	// if($num<=0x1FFFFF)   return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128).chr(($num&63)+128);
	//cerr<< hex<< cp<< " utf8chr -> { "<< chr[0]<< ' '<< chr[1]<< ' '<< chr[2]<< ' '<< chr[3]<< ' '<< chr[4]<< " }; "<< endl;
	return string(chu);
}


/**
 * Joins all contents from [ini,fin) into a string.

 * @param sep Joining string.
 * @param ini,fin Delimiters to the sequence of elements.
 */
template <typename String, typename Iterator1, typename Iterator2>
String join (String const& sep, Iterator1 ini, Iterator2 fin) {
    String ret;
    if (ini != fin) {
        std::stringstream ss; //<- needs to change to be generic
        ss<< *ini++;
................................................................................
            ss<< sep<< *ini;
        }
        ret= ss.str();
    }
    return ret;
}

// is this one necessary?
//! @overload join
template <typename Iterator1, typename Iterator2> inline 
std::string join (std::string const& sep, Iterator1 ini, Iterator2 fin) {
    return join<std::string>(sep,ini,fin);
}

/**
 * @brief Splits a string into a list of strings according to a separator.
 * @param sep Separator string.
 * @param ini Writable iterator where to deposit elements.
 * @return The value of the writable iterator after splitting is done.
 * 
 */
template <typename String, typename Iterator1, typename Number>
Iterator1 split_to (String const& sep, String const& str, Iterator1 ini, Number lim=0) {
    lim= 0;
    (void)lim;
    using namespace std;
    //typedef std::vector<String> VT;
    //typedef typename VT::const_iterator IT;

    //Iterator1 v = ini;
    //VT rt; rt.reserve ( count + 1 );
    //std::cout<< "[explode: found "<< count+1<< " ]"<< std::endl;
    typename String::const_iterator ci = begin(str);

    while (ci != end(str)) {
        // nothing here should cause rt to realloc.
        //cout<< "explode#"<< i<< ", pos="<< (ci-begin(str))<< endl;
        //typename String::const_iterator cn = find(ci, cend(str), sep[0] );
        typename String::const_iterator cn = search(ci, end(str), cbegin(sep), cend(sep));
        //if (ci == end(str)) break;
        String elem ( String (ci, cn) );
        ci= cn;
        *ini++= elem;
        if (ci == end(str)) { continue; } else { advance(ci, cend(sep)-cbegin(sep)); }
        //--i;
    }
    return ini;
}

//! @overload split_to
template <typename String, typename Iterator1>
Iterator1 split_to (String const& sep, String const& str, Iterator1 ini) {
    return split_to(sep, str, ini, 0);
}


/**
 * @brief Trims a string removing a selected character class from the left.
 * @param s The string object to be modified.
 * @param p Predicate for selecting the character class.
 * 
 */
template <typename String, typename Pred>
void l_trim (String& s, Pred p) {
    using namespace std;
    // we find L = first position in s where p(L) is false
    // we use string's erase function (or just a copy constructor)
    typename String::iterator L = find_if_not(begin(s), end(s), p);
    if (L == end(s)) return;
    s= String(L, end(s));
}


/**
 * @brief Trims a string removing a selected character class from the right.
 * @param s The string object to be modified.
 * @param p Predicate for selecting the character class.
 * 
 */
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());
}

/** Trims a string removing characters from the left and right. **/
template <typename String, typename Pred>
void trim (String& s, Pred p) {
    l_trim(s,p);
    r_trim(s,p);
}


} // string
/**
 * @}
 */

} // cxxomfort


#endif

Changes to cxxomfort/cxxomfort/library/tuplefn.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
..
79
80
81
82
83
84
85

86
87
88
89
90
91
92
...
150
151
152
153
154
155
156

157
158
159
160
161
162
163
...
205
206
207
208
209
210
211

212
213


214





215
216
217
218
219
220
221
#ifndef CXXOMFORT_CXXO_TUPLEFN_HPP
#define CXXOMFORT_CXXO_TUPLEFN_HPP
/**
 * @file library/tuplefn.hpp
 * @brief cxxomfort's tuple-related functions
 * @ingroup independent-features
 *
 * Interfaces defined:
 * 
 * * is_tuple
 * * tuple2function_t
 * * function2tuple_t
 * * tuple_pop
 * * tuple_shift
 * * tuple_foreach

 */

#include <tuple>
#include "../impl/14-integer_sequence.hpp"



























//
// is_tuple -- for specializations of calls based on tuples in C++03
namespace cxxomfort {
namespace tuple {
//

//! @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...> >
................................................................................


namespace cxxomfort {
namespace tuple {

/*
 * @brief Convert from tuple type to function signature.

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

template <typename Ret, typename Tuple> struct tuple2function_t {};

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


namespace cxxomfort {
namespace tuple {

/**
 * @brief Convert from function signature type to tuple type.

 * 
 * Given a function signature R(T1,T2,...), 
 * obtain a tuple of the form T<T1,T2,...>
 */
template <typename FnSig> struct function2tuple_t {};

#if (CXXOMFORT_CXX_STD >= 2011) 
................................................................................
}
} // cxxomfort


namespace cxxomfort {
namespace tuple {


/*
 * tuple_pop: removes the last type from a tuple


 */





#if (0 && CXXOMFORT_CXX_STD >= 2011)

//! Pops (discards) the rightmost type in a tuple.
//! @ingroup independent-utilities
template <typename AF, typename Args..., typename Indices...>
std::tuple<Args...> tuple_pop (std::tuple<Args...,AF> && _tuple) {
    using namespace std;





<




<
<



>




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







|







 







>







 







>







 







>
|
|
>
>
|
>
>
>
>
>







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
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
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
#ifndef CXXOMFORT_CXXO_TUPLEFN_HPP
#define CXXOMFORT_CXXO_TUPLEFN_HPP
/**
 * @file library/tuplefn.hpp
 * @brief cxxomfort's tuple-related functions

 *
 * Interfaces defined:
 * 
 * * is_tuple


 * * tuple_pop
 * * tuple_shift
 * * tuple_foreach
 * * tuple_call
 */

#include <tuple>
#include "../impl/14-integer_sequence.hpp"

namespace cxxomfort {
/**
 * @page cxxo:sup:tuple
 * 
 * This file provides supplementary features for the tuple-related 
 * utilities present in <code><tuple></code>.
 * 
 * Interfaces defined here
 * 
 * * @ref is_tuple
 * * @ref tuple_pop
 * * @ref tuple_shift
 * * @ref tuple2function_t
 * * @ref function2tuple_t
 * * @ref tuple_call
 * 
 * 
 * All interfaces are defined in the namespace <code>cxxomfort::algorithm::</code>.
 * 
 */

namespace tuple {
}
}


//
// is_tuple -- for specializations of calls based on tuples in C++03
namespace cxxomfort {
namespace tuple {
//

//! @addtogroup cxxo:sup:tuple
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...> >
................................................................................


namespace cxxomfort {
namespace tuple {

/*
 * @brief Convert from tuple type to function signature.
 * @ingroup cxxo:sup:tuple
 * 
 * Given a tuple of the form T<T1,T2,...>,
 * obtain a function signature R(T1,T2,...) 
 */

template <typename Ret, typename Tuple> struct tuple2function_t {};

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


namespace cxxomfort {
namespace tuple {

/**
 * @brief Convert from function signature type to tuple type.
 * @ingroup cxxo:sup:tuple
 * 
 * Given a function signature R(T1,T2,...), 
 * obtain a tuple of the form T<T1,T2,...>
 */
template <typename FnSig> struct function2tuple_t {};

#if (CXXOMFORT_CXX_STD >= 2011) 
................................................................................
}
} // cxxomfort


namespace cxxomfort {
namespace tuple {

#ifdef DOXYGEN_DOC
/**
 * @brief Removes the last type from a tuple
 * @ingroup cxxo:sup:tuple
 * 
 */
template <typename Tuple<A0, A1, ..., An> >
tuple<A1, ..., An> tuple_pop(tuple<A0, A1, ..., An> const&);

#endif

#if (0 && CXXOMFORT_CXX_STD >= 2011)

//! Pops (discards) the rightmost type in a tuple.
//! @ingroup independent-utilities
template <typename AF, typename Args..., typename Indices...>
std::tuple<Args...> tuple_pop (std::tuple<Args...,AF> && _tuple) {
    using namespace std;

Changes to cxxomfort/cxxomfort/library/type_name.hpp.

2
3
4
5
6
7
8

9
10
11
12
13


14
15
16
17
18
19
20
..
38
39
40
41
42
43
44
45
46
47
48

49
50


51
52
53
54
55
56
57
#define CXXOMFORT_TYPE_NAME_HPP
#include <cxxomfort/base.hpp>

/**
 * @file library/type_name.hpp
 * @brief Type naming and identification utilities in cxxomfort.
 * @ingroup independent-utilities

 */

#include <typeinfo>
#include <type_traits> // remove_reference, etc
#include "../util/type_traits.hpp"


#include <string>
#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC || CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_CLANG)
    #include <cxxabi.h>
#endif

namespace cxxomfort {
namespace detail_demangle {
................................................................................
}


} //detail_demangle::

//! Demangle a @c typeid() expression if demangling is available
//! @ingroup independent-features
static std::string typeid_demangle (std::type_info const& ti) {
    return detail_demangle::job( ti.name() );
}


//! Demangle a typename, recovering information about const / volatile too.
//! @ingroup independent-features


template <typename T>
std::string type_name () {
    using namespace std;
    typedef typename remove_reference<T>::type TnR;
    std::string r( typeid_demangle(typeid(T)) );
    if (is_const<TnR>::value) { r+= " const"; }
    if (is_volatile<TnR>::value) { r+= " volatile"; }







>





>
>







 







|



>
|
|
>
>







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#define CXXOMFORT_TYPE_NAME_HPP
#include <cxxomfort/base.hpp>

/**
 * @file library/type_name.hpp
 * @brief Type naming and identification utilities in cxxomfort.
 * @ingroup independent-utilities
 * @anchor library:type_name
 */

#include <typeinfo>
#include <type_traits> // remove_reference, etc
#include "../util/type_traits.hpp"
#include "../type_traits.hpp"
#include "../using.hpp"
#include <string>
#if (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_GCC || CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_CLANG)
    #include <cxxabi.h>
#endif

namespace cxxomfort {
namespace detail_demangle {
................................................................................
}


} //detail_demangle::

//! Demangle a @c typeid() expression if demangling is available
//! @ingroup independent-features
static inline std::string typeid_demangle (std::type_info const& ti) {
    return detail_demangle::job( ti.name() );
}

/**
 * @brief Demangle a typename, recovering information about const / volatile too.
 * @ingroup independent-features
 * @return A string containing a type name depending on the type @a T used to instantiate the function.
 */
template <typename T>
std::string type_name () {
    using namespace std;
    typedef typename remove_reference<T>::type TnR;
    std::string r( typeid_demangle(typeid(T)) );
    if (is_const<TnR>::value) { r+= " const"; }
    if (is_volatile<TnR>::value) { r+= " volatile"; }

Changes to cxxomfort/cxxomfort/library/typesafe_enum.hpp.

1
2
3
4
5
6
7
8
9
10


11
12
13
14
15
16
17
..
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
#ifndef CXXOMFORT_EXTRAS_SAFEENUM_HPP
#define CXXOMFORT_EXTRAS_SAFEENUM_HPP
/**
 @file cxxomfort/library/safeenum.hpp
 @author Luis Machuca Bezzaza
 @see http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Safe_Enum
 @see http://stackoverflow.com/questions/217549/which-typesafe-enum-in-c-are-you-using/11856721#11856721
**/
#include <cxxomfort/base.hpp>
#include <type_traits>



/*
 * Usage is as follows:
 */
#if 0 

// example
................................................................................

namespace detail_enum {
struct safe_enum_tag {};
} // detail_enum


template<typename def, typename inner = typename def::type>
class typesafe_enum : public def , public detail_enum::safe_enum_tag {
    inner val;
    public: 
    typedef typename def::type enum_type;
    typedef inner underlying_type;
 
    public:
    CXXO_CONSTEXPR typesafe_enum () CXXO_NOEXCEPT {}
    CXXO_CONSTEXPR typesafe_enum (typename def::type v) : val(v) {}
    CXXO_CONSTEXPR explicit typesafe_enum (underlying_type v) : val(v) {}
    CXXO_CONSTEXPR enum_type value() const CXXO_NOEXCEPT { return val; }
    CXXO_CONSTEXPR underlying_type underlying() const CXXO_NOEXCEPT { return val; }

    CXXO_EXPLICIT_OPERATOR(underlying_type)() const CXXO_NOEXCEPT { return val; }

    /*{
        enum { T_is_compatible_type = std::is_same<T, enum_type>::value };
        static_assert (T_is_compatible_type, "typesafe_enum construction invalid - not the enum's tags or the underlying type");
    };*/

    bool equals (typesafe_enum const& x) const CXXO_NOEXCEPT { return val == x.val; }
    
    private:
    struct disallowed_enum_conversion {};
    // we disallow other constructors
    template <typename T> 
    typesafe_enum (T const&, struct disallowed_enum_conversion* = nullptr
    , typename std::enable_if< std::is_integral<T>::value >::type * = nullptr);


    

    public:
/*
    template <typename E>
    typesafe_enum (E e
    , typename std::enable_if<std::is_enum<E>::value && !std::is_same<E,enum_type>::value
|
|
|
|






>
>







 







|











>
|












|
|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
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
#ifndef CXXOMFORT_LIBRARY_TYPESAFEENUM_HPP
#define CXXOMFORT_LIBRARY_TYPESAFEENUM_HPP
/**
 @file
 @author Luis Machuca Bezzaza
 @see http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Safe_Enum
 @see http://stackoverflow.com/questions/217549/which-typesafe-enum-in-c-are-you-using/11856721#11856721
**/
#include <cxxomfort/base.hpp>
#include <type_traits>
#include <cxxomfort/util/type_traits.hpp>
#include <cxxomfort/impl/11-conditional.hpp>

/*
 * Usage is as follows:
 */
#if 0 

// example
................................................................................

namespace detail_enum {
struct safe_enum_tag {};
} // detail_enum


template<typename def, typename inner = typename def::type>
class typesafe_enum : public def /*, public detail_enum::safe_enum_tag */ {
    inner val;
    public: 
    typedef typename def::type enum_type;
    typedef inner underlying_type;
 
    public:
    CXXO_CONSTEXPR typesafe_enum () CXXO_NOEXCEPT {}
    CXXO_CONSTEXPR typesafe_enum (typename def::type v) : val(v) {}
    CXXO_CONSTEXPR explicit typesafe_enum (underlying_type v) : val(v) {}
    CXXO_CONSTEXPR enum_type value() const CXXO_NOEXCEPT { return val; }
    CXXO_CONSTEXPR underlying_type underlying() const CXXO_NOEXCEPT { return val; }
    
    CXXO_EXPLICIT_OPERATOR(underlying_type) () const CXXO_NOEXCEPT { return val; }

    /*{
        enum { T_is_compatible_type = std::is_same<T, enum_type>::value };
        static_assert (T_is_compatible_type, "typesafe_enum construction invalid - not the enum's tags or the underlying type");
    };*/

    bool equals (typesafe_enum const& x) const CXXO_NOEXCEPT { return val == x.val; }
    
    private:
    struct disallowed_enum_conversion {};
    // we disallow other constructors
    template <typename T> 
    typesafe_enum (T const&, 
     typename std::enable_if< 
        std::is_integral<T>::value , disallowed_enum_conversion 
        >::type * = 0 );
    

    public:
/*
    template <typename E>
    typesafe_enum (E e
    , typename std::enable_if<std::is_enum<E>::value && !std::is_same<E,enum_type>::value

Changes to cxxomfort/cxxomfort/limits.hpp.

1
2
3
4
5
6

7
8
9
10
11
12
13
..
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#ifndef CXXOMFORT_LIMITS_HPP
#define CXXOMFORT_LIMITS_HPP
/**
 * @file cxxomfort/limits.hpp
 * @brief Compile-time expressions for integral @c <limits> values in C++
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>

 *
 * Interfaces defined in this header:
 *
 * * cxxomfort::integral_limits
 *
 */

................................................................................
struct log_<0, base> {
    enum { value = 0 };
};


}


template <typename T>
struct integral_limits {
    static_assert (std::is_integral<T>::value, "integral_limits is only defined for compiler integral types");
};

#define SPECIA_IMPL(Ty_,Min_,Max_) \
template <> struct integral_limits<Ty_>           \



|
|
|
>







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
..
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#ifndef CXXOMFORT_LIMITS_HPP
#define CXXOMFORT_LIMITS_HPP
/**
 * @file
 * @brief Compile-time expressions for integral @c <limits> values in C++
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 * @ingroup independent-features
 *
 * Interfaces defined in this header:
 *
 * * cxxomfort::integral_limits
 *
 */

................................................................................
struct log_<0, base> {
    enum { value = 0 };
};


}

//! @ingroup independent-features
template <typename T>
struct integral_limits {
    static_assert (std::is_integral<T>::value, "integral_limits is only defined for compiler integral types");
};

#define SPECIA_IMPL(Ty_,Min_,Max_) \
template <> struct integral_limits<Ty_>           \

Changes to cxxomfort/cxxomfort/memory.hpp.

70
71
72
73
74
75
76

77
78
79
80
81
82
83
...
116
117
118
119
120
121
122

123
124
125
126
127
128
129
...
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
168
169
170
171
172
173
174
175


176

#include CXXO_INCLUDE_SYS(memory)
#include "base.hpp"

// We define alignas, alignof depending on compiler specifics
#if 0
#elif (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_GCC)

#elif (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_MSC)
#else // unrecognized compiler, we can't go any further
    // take a safe bet
    #define alignof(T) __alignof(T)
    // this bet is very unsafe, but nothing better can be done at this point
    #define alignas(N) typedef *char _cant_implement_alignas_emulation[-1]
    #pragma message CXXO_NOTICE("alignof directives not supported; compilation might fail if using <memory> utilities!")
................................................................................
    } type;
};
#else
    #if defined(__GNUC__) && (CXXOMFORT_COMPILER_VERSION >= 406)
    // in GCC >= 4.6, __attribute__(aligned) can take compile-time constants
    #elif defined(__GNUC__) && (CXXOMFORT_COMPILER_VERSION >= 402)
    // in GCC >= 4.2, __attribute__(aligned) can only take numeric literals

    // in MSC (tested versions), __declspec(aligned) can only take numeric literals

    #elif defined(_MSC_VER)
    #else
    #error ("Unidentified method for aligned_storage.");

    #endif
................................................................................
#include "impl/11-addressof.hpp"


//
// unique_ptr
//
#include "impl/unique_ptr.hpp"
#include "impl/make_unique.hpp"




// -- set up needed things in std::


#else
#include <memory>
namespace cxxomfort {
................................................................................
    using std::uninitialized_copy_n;
    using std::aligned_storage;
}


#endif // c++03/11




#endif // file







>







 







>







 







<
<
<
<







 







|
>
>
|
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
...
151
152
153
154
155
156
157




158
159
160
161
162
163
164
...
166
167
168
169
170
171
172
173
174
175
176

#include CXXO_INCLUDE_SYS(memory)
#include "base.hpp"

// We define alignas, alignof depending on compiler specifics
#if 0
#elif (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_GCC)
#elif (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_CLANG)
#elif (CXXOMFORT_COMPILER_ID == CXXO_VALUE_COMPILER_MSC)
#else // unrecognized compiler, we can't go any further
    // take a safe bet
    #define alignof(T) __alignof(T)
    // this bet is very unsafe, but nothing better can be done at this point
    #define alignas(N) typedef *char _cant_implement_alignas_emulation[-1]
    #pragma message CXXO_NOTICE("alignof directives not supported; compilation might fail if using <memory> utilities!")
................................................................................
    } type;
};
#else
    #if defined(__GNUC__) && (CXXOMFORT_COMPILER_VERSION >= 406)
    // in GCC >= 4.6, __attribute__(aligned) can take compile-time constants
    #elif defined(__GNUC__) && (CXXOMFORT_COMPILER_VERSION >= 402)
    // in GCC >= 4.2, __attribute__(aligned) can only take numeric literals
    #elif (CXXOMFORT_COMPILER_ID==CXXO_VALUE_COMPILER_CLANG) 
    // in MSC (tested versions), __declspec(aligned) can only take numeric literals

    #elif defined(_MSC_VER)
    #else
    #error ("Unidentified method for aligned_storage.");

    #endif
................................................................................
#include "impl/11-addressof.hpp"


//
// unique_ptr
//
#include "impl/unique_ptr.hpp"





// -- set up needed things in std::


#else
#include <memory>
namespace cxxomfort {
................................................................................
    using std::uninitialized_copy_n;
    using std::aligned_storage;
}


#endif // c++03/11


#include "impl/14-make_unique.hpp"

#endif // file

Added cxxomfort/cxxomfort/numeric.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
#ifndef CXXOMFORT_NUMERIC_HPP
#define CXXOMFORT_NUMERIC_HPP
/**
 * @file numeric.hpp
 * @brief Header file for the <algorithm>-related backports.
 * @ingroup numeric
 */

#include "base.hpp"
#include "util/meta.hpp" // conditional
#include CXXO_INCLUDE_SYS(numeric)


namespace cxxomfort {
namespace numeric {

//! 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;
}

//! Fills @p n elements with an incrementing sequence starting from @p i0 .
template <typename FwIt, typename Integer, typename T>
FwIt iota_n (FwIt ini, Integer n, T i0) {
    while (n-->0) { *ini= i0; ++ini; ++i0; }
    return ini;
}


} //~namespace numeric
} //~namespace cxxomfort

namespace cxxomfort {
namespace numeric {

// see: https://en.cppreference.com/w/cpp/numeric/gcd 

template <typename IM, typename IN>
CXXO_CONSTEXPR IM gcd (IM m, IN n) CXXO_NOEXCEPT {
    return (n== 0) ? m : gcd(n, m % n);
}

template <typename IM, typename IN>
CXXO_CONSTEXPR IM lcm (IM m, IN n) CXXO_NOEXCEPT {
    return m / gcd(m,n) * n;
}

} // numeric
}


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

#if (CXXOMFORT_CXX_STD < 2011) && (CXXO_COMPILER_SUPPORT_std_cxx11_algorithms == 0)
#if (!defined(CXXOMFORT_NO_STD_USING))
namespace std {
    using ::cxxomfort::numeric::iota;
}
#endif // std using

#endif // using emulation

#if (!defined(CXXOMFORT_NO_STD_USING))
#if (CXXOMFORT_CXX_STD < 2017)
namespace std {
    using ::cxxomfort::numeric::gcd;
    using ::cxxomfort::numeric::lcm;
}
#endif
#endif // no std using

#endif

Changes to cxxomfort/cxxomfort/random.hpp.

1
2
3
4
5
6
7
8
9
10
11
..
41
42
43
44
45
46
47

48
49
50
51
52
#ifndef CXXOMFORT_RANDOM_HPP
#define CXXOMFORT_RANDOM_HPP
/**
 * @file cxxomfort/random.hpp
 * @brief Fixes and backports from <random>.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces defined in this header:
 *
 *
 */
................................................................................
};

template <typename TD, typename TG>
random_wrapper<TD,TG> make_random_wrap (TD& d, TG& g) {
    return random_wrapper<TD,TG>(d,g);
}



}


#endif



|







 







>
|
<
<
<
|
1
2
3
4
5
6
7
8
9
10
11
..
41
42
43
44
45
46
47
48
49



50
#ifndef CXXOMFORT_RANDOM_HPP
#define CXXOMFORT_RANDOM_HPP
/**
 * @file
 * @brief Fixes and backports from <random>.
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces defined in this header:
 *
 *
 */
................................................................................
};

template <typename TD, typename TG>
random_wrapper<TD,TG> make_random_wrap (TD& d, TG& g) {
    return random_wrapper<TD,TG>(d,g);
}

} // cxxomfort




#endif

Changes to cxxomfort/cxxomfort/sequences.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_SEQUENCES_HPP
#define CXXOMFORT_SEQUENCES_HPP
/**
 * @file cxxomfort/sequences.hpp
 * @brief Improvements for <array>, <valarray> and generic containers in C++03, C++11.
 * 













 * Interfaces defined in this file:
 * 
 * * @c is_std_array
 * * @c is_sequence_container
 * * @c is_indexable_like_array
 * * @c is_iterator
 * * @c make_array
 * * @c seq_ , @c generic_sequence_t
 * 
 * Pending:
 * 
 * * @c array<> in C++03 mode with NO_TR1 defined
 *

 */

#include "config.hpp"
#include <array>
#include <vector>
#include <type_traits>
#include "library/i12n.hpp"
#include "using.hpp"


//
// is_std_array
//

namespace cxxomfort {







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













>
|
|
<
<
<
<
<
<
<







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
#ifndef CXXOMFORT_SEQUENCES_HPP
#define CXXOMFORT_SEQUENCES_HPP
/**
 * @file cxxomfort/sequences.hpp
 * @brief Improvements for <array>, <valarray> and generic containers in C++03, C++11.
 * 
 */

#include "config.hpp"
#include <array>
#include <vector>
#include <type_traits>
#include "library/i12n.hpp"
#include "using.hpp"

/**
 * @page Sequence Helpers
 * @ingroup independent-features
 * 
 * Interfaces defined in this file:
 * 
 * * @c is_std_array
 * * @c is_sequence_container
 * * @c is_indexable_like_array
 * * @c is_iterator
 * * @c make_array
 * * @c seq_ , @c generic_sequence_t
 * 
 * Pending:
 * 
 * * @c array<> in C++03 mode with NO_TR1 defined
 *

 */









//
// is_std_array
//

namespace cxxomfort {

Changes to cxxomfort/cxxomfort/string.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
#ifndef CXXOMFORT_STRING_HPP
#define CXXOMFORT_STRING_HPP
/**
 * @file cxxomfort/string.hpp
 * @brief Implementations and additions tied to <string>.

 * Interfaces defined in this header:
 *
 * * to_string and others
 *
 */


/**
 * @addtogroup string
 * @{
 */

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










#include "impl/11-to_string.hpp"
// #include "impl/string.hpp" // custom string functions






/**
 * @}
 */

#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
30
31
32
33
34
35
36
37
38
#ifndef CXXOMFORT_STRING_HPP
#define CXXOMFORT_STRING_HPP
/**
 * @file
 * @brief Implementations and backports related to <code><string></code>.
 * 
 * Interfaces defined in this header:
 *
 * * to_string() (C++11) and others
 *
 */







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

namespace cxxomfort {
/**
 * @namespace
 * @brief Namespace for <string>-related utilities in cxxomfort.
 */
namespace string {
}
}

#include "impl/11-to_string.hpp"

//#include "impl/14-string_literal.hpp"

/**
 * @{
 */

/**
 * @}
 */

#endif

Changes to cxxomfort/cxxomfort/tuple.hpp.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
..
25
26
27
28
29
30
31

32
33
34
35
36
37
38
..
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
...
211
212
213
214
215
216
217


218









219
220
221
#ifndef CXXOMFORT_TUPLE_HPP
#define CXXOMFORT_TUPLE_HPP
/**
 * @file cxxomfort/tuple.hpp
 * @brief Implementations for <tuple> in C++
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 *
 * Interfaces defined in this header:
 *
 * * cxxomfort::is_tuple
 * * tuple2array
 * * get<T> for std::tuple (c++14)
 * * apply(function,tuple) (c++17)

 *
 */

#include "base.hpp"
#include "utility.hpp" // index_sequence
#include <tuple> // d'uh
#include <array> // array <-> tuple conversions
................................................................................
#endif

#include "impl/14-tuple_get_type.hpp" // std::get<T> (tuple<>)
#include "impl/17-tuple_apply.hpp" // std::apply (Function, tuple<>)
#include "impl/17-make_from_tuple.hpp" // std::make_from_tuple<T>(tuple<>)

namespace cxxomfort {

namespace tuple {

template <typename Tuple>
struct _tuple2array_cnv_t {
    // Tuple is a tuple
    static_assert (is_tuple<Tuple>::value, "tuple_to_array: T must be a tuple");
    typedef /* typename std::decay<Tuple>::type */ Tuple InTuple;
................................................................................
    _tuple2array_cnv_t (Tuple const& t): _t(t) {}
    // conversion operator to an array of the same size as the tuple
#if (1 && ( CXXOMFORT_CXX_STD >= 2011 || (CXXOMFORT_CXX_EMULATION == 2011 && CXXO_EMULATION_variadic && CXXO_EMULATION_rvref)))
    template<size_t... I>
    std::array<U,_S> get_array (std::index_sequence<I...>) const {
        using std::get;
        using std::forward;
        return std::array<U,_S> { get<I>((_t))... };
    }


    template <typename Indices = std::make_index_sequence<std::tuple_size<InTuple>::value> >
    operator std::array<U,_S> () const {
        return get_array(Indices());
    }
................................................................................
_array2tuple_cnv_t<std::array<T,N> > array2tuple (std::array<T,N> const& a) {
    return _array2tuple_cnv_t< std::array<T,N> >(a);
}

} //cxxomfort::tuple
} //














#endif




|
|

|





|
>







 







>







 







|







 







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



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
..
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
...
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#ifndef CXXOMFORT_TUPLE_HPP
#define CXXOMFORT_TUPLE_HPP
/**
 * @file
 * @brief Implementations and additions for <tuple> in C++
 * @author Luis Machuca Bezzaza <luis [dot] machuca [at] gulix [dot] cl>
 * 
 * Interfaces defined in this header:
 *
 * * cxxomfort::is_tuple
 * * tuple2array
 * * get<T> for std::tuple (c++14)
 * * @ref apply(function,tuple) (c++17)
 * * @ref make_from_tuple (c++17)
 *
 */

#include "base.hpp"
#include "utility.hpp" // index_sequence
#include <tuple> // d'uh
#include <array> // array <-> tuple conversions
................................................................................
#endif

#include "impl/14-tuple_get_type.hpp" // std::get<T> (tuple<>)
#include "impl/17-tuple_apply.hpp" // std::apply (Function, tuple<>)
#include "impl/17-make_from_tuple.hpp" // std::make_from_tuple<T>(tuple<>)

namespace cxxomfort {
//! @brief Components related to <tuple>
namespace tuple {

template <typename Tuple>
struct _tuple2array_cnv_t {
    // Tuple is a tuple
    static_assert (is_tuple<Tuple>::value, "tuple_to_array: T must be a tuple");
    typedef /* typename std::decay<Tuple>::type */ Tuple InTuple;
................................................................................
    _tuple2array_cnv_t (Tuple const& t): _t(t) {}
    // conversion operator to an array of the same size as the tuple
#if (1 && ( CXXOMFORT_CXX_STD >= 2011 || (CXXOMFORT_CXX_EMULATION == 2011 && CXXO_EMULATION_variadic && CXXO_EMULATION_rvref)))
    template<size_t... I>
    std::array<U,_S> get_array (std::index_sequence<I...>) const {
        using std::get;
        using std::forward;
        return std::array<U,_S> { { get<I>((_t))... } };
    }


    template <typename Indices = std::make_index_sequence<std::tuple_size<InTuple>::value> >
    operator std::array<U,_S> () const {
        return get_array(Indices());
    }
................................................................................
_array2tuple_cnv_t<std::array<T,N> > array2tuple (std::array<T,N> const& a) {
    return _array2tuple_cnv_t< std::array<T,N> >(a);
}

} //cxxomfort::tuple
} //

/**
 * @page std:tuple
 * 
 * Features part of the <tuple>-related backports:
 * 
 * * @ref get<tuple>()
 * * @ref tupple_apply()
 * * @ref make_from_tuple()
 * 
 * See also: @ref std:utility .
 * 
 */

#endif

Changes to cxxomfort/cxxomfort/type_traits.hpp.

18
19
20
21
22
23
24



25
26
27
28
29
30
31
32
33
34
 * * @c is_null_pointer (from c++14)
 * * @c make_void (from c++17)
 *
 *  * TODO: TR1 fixes for c++03 (eg.: is_trivial) should go to a separate forwarding library.
 * 
 */




#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









>
>
>
|
|
<







18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
 * * @c is_null_pointer (from c++14)
 * * @c make_void (from c++17)
 *
 *  * TODO: TR1 fixes for c++03 (eg.: is_trivial) should go to a separate forwarding library.
 * 
 */

#include "impl/11-conditional.hpp"
#include "util/type_traits.hpp"
#include "util/meta.hpp" // enable_if etc
#include "utility.hpp" // declval
#include <type_traits>

#include "using.hpp" // bring TR1 in

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


Changes to cxxomfort/cxxomfort/using.hpp.

1
2



3
4
5
6
7
8
9
..
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
#ifndef CXXOMFORT_USING_HPP
#define CXXOMFORT_USING_HPP



// this header should be included after all other standard
// headers that are needed have been included
// in other words: #include as late as possible.
// compliments http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36428 in GCC

#include "config.hpp"

................................................................................
// Check your compiler's documentation to see how to do this.
//

/**
 * @namespace std
 * @brief Namespace of the Standard C++ Features
 * 
 * The cxxomfort library maps some features inside this namespace for 
 * backporting. All features mapped this way are brought via 
 * @c using -declaration, with no implementation details entering 
 * the namespace.
 * 
 */
#if (CXXOMFORT_CXX_STD < 2011 && CXXOMFORT_CXX_EMULATION < 2011)
namespace std { namespace tr1 {} } // ensure that the tr1 name exists
namespace std { 
    using namespace tr1 ;   
    // the above uses the contents of namespace 
    // might be not safe, see http://lists.nongnu.org/archive/html/adonthell-general/2011-07/msg00008.html
    // but there's really no better choice when trying to write 
    // portable code because:
    // 1.- we can't know in advance what names are exposed to "using" them
    // eg.: incomplete TR1 implementations, features that change names 
    // such as the ones in <random>
    // see http://lists.gnu.org/archive/html/adonthell-devel/2011-07/msg00000.html

    // 2.- we can't make the object names appear without 
    // #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.

}


>
>
>







 







<
<
<
<
|
<
|











>







1
2
3
4
5
6
7
8
9
10
11
12
..
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_USING_HPP
#define CXXOMFORT_USING_HPP
/**
 * @file
 */
// this header should be included after all other standard
// headers that are needed have been included
// in other words: #include as late as possible.
// compliments http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36428 in GCC

#include "config.hpp"

................................................................................
// Check your compiler's documentation to see how to do this.
//

/**
 * @namespace std
 * @brief Namespace of the Standard C++ Features
 * 




 */

#if (CXXOMFORT_CXX_STD < 2011 /* && CXXOMFORT_CXX_EMULATION < 2011 */)
namespace std { namespace tr1 {} } // ensure that the tr1 name exists
namespace std { 
    using namespace tr1 ;   
    // the above uses the contents of namespace 
    // might be not safe, see http://lists.nongnu.org/archive/html/adonthell-general/2011-07/msg00008.html
    // but there's really no better choice when trying to write 
    // portable code because:
    // 1.- we can't know in advance what names are exposed to "using" them
    // eg.: incomplete TR1 implementations, features that change names 
    // such as the ones in <random>
    // see http://lists.gnu.org/archive/html/adonthell-devel/2011-07/msg00000.html
    // (and we can't ignore missing names because "using" an unknown name is a fatal error)
    // 2.- we can't make the object names appear without 
    // #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.

}

Changes to cxxomfort/cxxomfort/util/memtraits.hpp.

154
155
156
157
158
159
160

161
162
163
164
165

166
167
168
169
170
171
172
    
    static pointer allocate (Alloc &a, size_type n) { return a.allocate(n); }
    static pointer allocate (Alloc &a, size_type n, const void* hint) { return a.allocate(n,hint); }
    static void    deallocate (Alloc &a, pointer p, size_type n) { a.deallocate(p,n); }
    template <typename T>
    static void construct (Alloc &a, T* p) { 
        //a.construct(p); 

        ::new (static_cast<void*>(p)) T;
        }
    template <typename T>
    static void construct (Alloc &a, T* p, CXXO_RV_REF(T) m) { 
        //a.construct(p,std::forward<T>(m)); 

        ::new (static_cast<void*>(p)) T (std::move(m));
    }
    template <typename T, typename Arg1>
    static void construct (Alloc& a, T* p, Arg1 x1) { a.construct(p,x1); }
    template <typename T, typename Arg1, typename Arg2>
    static void construct (Alloc& a, T* p, Arg1 x1, Arg2 x2) { a.construct(p,x1,x2); }
    template <typename T>







>





>







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    
    static pointer allocate (Alloc &a, size_type n) { return a.allocate(n); }
    static pointer allocate (Alloc &a, size_type n, const void* hint) { return a.allocate(n,hint); }
    static void    deallocate (Alloc &a, pointer p, size_type n) { a.deallocate(p,n); }
    template <typename T>
    static void construct (Alloc &a, T* p) { 
        //a.construct(p); 
        (void)a;
        ::new (static_cast<void*>(p)) T;
        }
    template <typename T>
    static void construct (Alloc &a, T* p, CXXO_RV_REF(T) m) { 
        //a.construct(p,std::forward<T>(m)); 
        (void)a;
        ::new (static_cast<void*>(p)) T (std::move(m));
    }
    template <typename T, typename Arg1>
    static void construct (Alloc& a, T* p, Arg1 x1) { a.construct(p,x1); }
    template <typename T, typename Arg1, typename Arg2>
    static void construct (Alloc& a, T* p, Arg1 x1, Arg2 x2) { a.construct(p,x1,x2); }
    template <typename T>

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

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
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
 * * 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
 */
template <typename T>
struct identity {  typedef T type; };

/**
 * @struct enable_if
 * @brief Given condition Cond, define member ::type as T only if Cond is @c true ; otherwise define nothing.
 */
template <bool Cond, typename T=void> struct enable_if;
template <typename T> struct enable_if<true,T> { typedef T type; }; ///< actually defined only in this case

/**
 * @name disable_if
 * @brief Oppossite of @c enable_if , added here for completeness.
 */
template <bool B, typename T=void> struct disable_if { typedef T type; };
template <typename T> struct enable_if<true,T>;

/**
 * @brief Given condition @e Cond , define member ::type as T1 if Cond is @c false , as T2 otherwise.
 */
template <bool Cond, typename T1, typename T2> struct conditional        { typedef T2 type; };
template <typename T1, typename T2> struct conditional<true,T1,T2>    { typedef T1 type; };

/**
 * @brief Given an index V and a list of types T0, T1, T2, ...; find the type in the Vth position.
 */
template <unsigned V,
    typename T0, typename T1, typename T2= void, typename T3= void, typename T4= void,
    typename T5= void, typename T6= void, typename T7= void, typename T8= void, typename T9= void>
struct selection {};
................................................................................

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


//
// enable_if and conditional go to namespace std
//
namespace std {
    using ::cxxomfort::enable_if;
    using ::cxxomfort::conditional;
}

// Example usages
// http://stackoverflow.com/questions/7693703/can-i-use-something-like-enable-if-with-an-implicit-conversion-operator?rq=1
//
//

#endif // USING

#endif // file







>







 







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







 







<
<
<
<
<
<
<
<








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
...
228
229
230
231
232
233
234








235
236
237
238
239
240
241
242
 * * selection
 * * meta_and, meta_or
 * 
 */

#include <cxxomfort/config.hpp>
#include <cxxomfort/base/static_assert.hpp>
#include <cxxomfort/impl/11-conditional.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
 */
template <typename T>
struct identity {  typedef T type; };





















/**
 * @brief Given an index V and a list of types T0, T1, T2, ...; find the type in the Vth position.
 */
template <unsigned V,
    typename T0, typename T1, typename T2= void, typename T3= void, typename T4= void,
    typename T5= void, typename T6= void, typename T7= void, typename T8= void, typename T9= void>
struct selection {};
................................................................................

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










// Example usages
// http://stackoverflow.com/questions/7693703/can-i-use-something-like-enable-if-with-an-implicit-conversion-operator?rq=1
//
//

#endif // USING

#endif // file

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

Changes to cxxomfort/cxxomfort/util/type_traits.hpp.

Changes to cxxomfort/cxxomfort/utility.hpp.

1
2
3
4

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
27
28
29
30
31
32
33






34
35
36

37
38
39
40
41
42
43
..
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#ifndef CXXOMFORT_UTILITY_HPP
#define CXXOMFORT_UTILITY_HPP
/**
 * @file cxxomfort/utility.hpp

 * @brief Implementations and additions tied to <utility>.
 * 
 * Interfaces defined in this file:
 * 
 * * declval
 * * exchange
 * * move (from util/move)
 * * forward (from util/move)
 * * as_const (from c++17)
 * 
 * Interfaces reflected in namespace @b std : 
 * 
 * * declval
 * * exchange
 * * as_const 
 * 
................................................................................

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


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)
................................................................................
            #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()



|
>




|
|
|
|
|







 







>
>
>
>
>
>
|
|
|
>







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
..
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#ifndef CXXOMFORT_UTILITY_HPP
#define CXXOMFORT_UTILITY_HPP
/**
 * @file
 * @page std:utility
 * @brief Implementations and additions tied to <utility>.
 * 
 * Interfaces defined in this file:
 * 
 * * declval()
 * * exchange()
 * * move (from util/move)
 * * forward (from util/move)
 * * as_const() (from c++17)
 * 
 * Interfaces reflected in namespace @b std : 
 * 
 * * declval
 * * exchange
 * * as_const 
 * 
................................................................................

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


namespace cxxomfort {
/**
 * @namespace
 * @brief Namespace for the <utility>-related backports and features in cxxomfort.
 */
namespace utility {
    //! Unevaluated context.
    //! @ingroup utility
    //! @ingroup cxx11-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)
................................................................................
            #define CXXO_ADD_declval
        #endif
    #else
        #define CXXO_ADD_declval
    #endif
    #if defined(CXXO_ADD_declval)
namespace std { 
    using ::cxxomfort::utility::declval;
} //std::
        #undef CXXO_ADD_declval
    #endif

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

Changes to cxxomfort/cxxomfort/various.hpp.

1
2
3
4
5
6
7
8
9
10
11
#ifndef CXXOMFORT_UTILITIES_HPP
#define CXXOMFORT_UTILITIES_HPP
/**
 * @file cxxomfort/utilities.hpp
 * @author Luis Machuca Bezzaza
 * @brief Implements a set of library-specific utilities for cxxomfort, 
 * not mapped to C++03 or C++11 facilities.
 * 
 * ==No other base cxxomfort feature should depend on these utilities==
 * 
 * Interfaces defined in this file:



|







1
2
3
4
5
6
7
8
9
10
11
#ifndef CXXOMFORT_UTILITIES_HPP
#define CXXOMFORT_UTILITIES_HPP
/**
 * @file
 * @author Luis Machuca Bezzaza
 * @brief Implements a set of library-specific utilities for cxxomfort, 
 * not mapped to C++03 or C++11 facilities.
 * 
 * ==No other base cxxomfort feature should depend on these utilities==
 * 
 * Interfaces defined in this file:

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

34
35
36
37
38
39
40

41
42
43


44
45
46
47

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








>



>
>

<


>
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
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_inplace_if|Iterator|(Iterator ini, Iterator fin, Function f, Predicate p)|
transform_n|Iterator|(Iterator ini, Integer n, DestIterator out, Function f)|
#functional
#string
to_string|std::string|(expressions..., )|
to_wstring|std::wstring|(expressions..., )|
#tuple

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)>)|
#utility