Changeset 389


Ignore:
Timestamp:
06/11/15 12:13:28 (10 years ago)
Author:
epyon
Message:
  • stl functional extensions
  • stl algorithm clenups
  • stl memory/iterator/string clenups
  • experimental type_traits
Location:
trunk
Files:
3 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/stl/algorithm/common.hh

    r388 r389  
    1818namespace nv
    1919{
     20
    2021}
    2122
  • trunk/nv/stl/algorithm/copy.hh

    r388 r389  
    1616#include <nv/stl/algorithm/common.hh>
    1717#include <nv/stl/algorithm/raw.hh>
     18#include <nv/stl/iterator.hh>
     19#include <nv/stl/type_traits/common.hh>
    1820
    1921namespace nv
  • trunk/nv/stl/algorithm/fill.hh

    r388 r389  
    1616#include <nv/stl/algorithm/common.hh>
    1717#include <nv/stl/algorithm/raw.hh>
     18#include <nv/stl/iterator.hh>
     19#include <nv/stl/type_traits/common.hh>
    1820
    1921namespace nv
  • trunk/nv/stl/functional/comparisons.hh

    r387 r389  
    2020
    2121        template< typename T = void >
     22        struct equal_to
     23        {
     24                typedef bool result_type;
     25                typedef T first_argument_type;
     26                typedef T second_argument_type;
     27
     28                constexpr bool operator() ( const T& lhs, const T& rhs ) const
     29                {
     30                        return lhs == rhs;
     31                }
     32        };
     33
     34        template<>
     35        struct equal_to< void >
     36        {
     37                typedef is_transparent_t is_transparent;
     38
     39                template < typename T1, typename T2 >
     40                constexpr auto operator() ( T1&& lhs, T2&& rhs ) const
     41                        -> decltype( static_cast<T1&&>( lhs ) == static_cast<T2&&>( rhs ) )
     42                {
     43                        return static_cast<T1&&>( lhs ) == static_cast<T2&&>( rhs );
     44                }
     45        };
     46
     47        template< typename T = void >
    2248        struct not_equal_to
    2349        {
    24                 typedef T result_type;
     50                typedef bool result_type;
    2551                typedef T first_argument_type;
    2652                typedef T second_argument_type;
     
    4874        struct greater
    4975        {
    50                 typedef T result_type;
     76                typedef bool result_type;
    5177                typedef T first_argument_type;
    5278                typedef T second_argument_type;
     
    74100        struct less
    75101        {
    76                 typedef T result_type;
     102                typedef bool result_type;
    77103                typedef T first_argument_type;
    78104                typedef T second_argument_type;
     
    101127        struct greater_equal
    102128        {
    103                 typedef T result_type;
     129                typedef bool result_type;
    104130                typedef T first_argument_type;
    105131                typedef T second_argument_type;
     
    127153        struct less_equal
    128154        {
    129                 typedef T result_type;
     155                typedef bool result_type;
    130156                typedef T first_argument_type;
    131157                typedef T second_argument_type;
  • trunk/nv/stl/functional/reference.hh

    r387 r389  
    1414#define NV_STL_FUNCTIONAL_REFERENCE_HH
    1515
    16 #include <nv/core/common.hh>
     16#include <nv/stl/functional/common.hh>
     17#include <nv/stl/functional/invoke.hh>
    1718
    1819namespace nv
     
    2526                typedef T type;
    2627
    27                 reference_wrapper( type& ref ) noexcept : m_pointer( std::addressof( ref ) ) {}
     28                reference_wrapper( type& ref ) noexcept : m_pointer( addressof( ref ) ) {}
    2829                reference_wrapper( type&& ) = delete;
    2930                reference_wrapper( const reference_wrapper& ) noexcept = default;
     
    3132                operator type& ( ) const noexcept { return *m_pointer; }
    3233                type& get() const noexcept { return *m_pointer; }
     34
     35                template< typename... Args >
     36                typename result_of<T&( Args&&... )>::type
     37                        operator()( Args&&... args ) const
     38                {
     39                        return ( invoke( get(), forward<Args>( args )... ) );
     40                }
    3341        private:
    3442                type* m_pointer;
  • trunk/nv/stl/iterator.hh

    r378 r389  
    200200        template < typename InputIterator >
    201201        inline typename iterator_traits< InputIterator >::difference_type
    202         distance( InputIterator first, InputIterator last )
     202                distance( InputIterator first, InputIterator last )
    203203        {
    204204                typedef typename iterator_traits< InputIterator >::iterator_category category;
     
    206206        }
    207207
     208        // Returns 0 for input iterators, distance for others
     209        // this is an extension to the standard
     210        template < typename InputIterator >
     211        inline typename iterator_traits< InputIterator >::difference_type
     212                estimate_distance( InputIterator first, InputIterator last )
     213        {
     214                typedef typename iterator_traits< InputIterator >::iterator_category category;
     215                return !is_same< category, input_iterator_tag >::value ? detail::distance_impl( first, last, category() ) : 0;
     216        }
     217
     218
    208219        template < typename InputIterator, typename Distance >
    209220        inline void advance( InputIterator& iter, Distance n )
  • trunk/nv/stl/memory.hh

    r385 r389  
    2525namespace nv
    2626{
    27         namespace detail
    28         {
    29                 template< typename T >
    30                 struct addressof_helper
    31                 {
    32                         T & value;
    33                         constexpr addressof_helper( T & v ) : value( v ) {}
    34                         constexpr operator T& () const { return value; }
    35                 private:
    36                         addressof_helper & operator=( const addressof_helper & );
    37                 };
    38 
    39                 template< typename T >
    40                 struct addressof_impl
    41                 {
    42                         static constexpr T * f( T & v, long )
    43                         {
    44                                 return reinterpret_cast<T*>(
    45                                         &const_cast<char&>( reinterpret_cast<const volatile char &>( v ) ) );
    46                         }
    47                         static constexpr T * f( T * v, int ) { return v; }
    48                 };
    49         }
    50 
    51         template< typename T >
    52         T * addressof( T & v )
    53         {
    54                 return detail::addressof_impl<T>::f( detail::addressof_helper<T>( v ), 0 );
    55         }
     27
    5628
    5729        namespace mem_flags
  • trunk/nv/stl/string.hh

    r385 r389  
    3131namespace nv
    3232{
     33
     34
     35//      short_string< size_t >
     36//      string32
     37//      string64
     38//      string
     39
     40
    3341        /**
    3442        * Simple function for slurping a file into a string.
     
    384392NV_STRING_BASE_CAST_OPERATORS( >= )
    385393
    386         inline std::ostream& operator<<( std::ostream& os, const string_base& str )
    387         {
    388                 if ( os.good() )
    389                 {
    390                         os.write( str.data(), static_cast<std::streamsize>( str.size() ) );
    391                 }
    392                 return os;
    393         }
    394394
    395395#undef NV_STRING_REF_CAST_OPERATORS
  • trunk/nv/stl/type_traits/common.hh

    r382 r389  
    7676        // TODO END
    7777
     78        template < typename T > struct is_lvalue_reference : false_type {};
     79        template < typename T > struct is_lvalue_reference < T& > : true_type{};
     80        template < typename T > struct is_rvalue_reference : false_type {};
     81        template < typename T > struct is_rvalue_reference < T&& > : true_type{};
     82
     83        template < typename T >
     84        struct is_reference : bool_constant <
     85                is_lvalue_reference<T>::value ||
     86                is_rvalue_reference<T>::value
     87        > {};
     88
    7889        // add const volatile and reference mutators
    7990
     
    8293        template< typename T > struct add_cv             { typedef const volatile T type; };
    8394       
    84         template< typename T > struct add_reference             { typedef T& type; };
     95        template< typename T > struct add_reference             
     96        {
     97                typedef typename conditional< is_reference<T>::value, T, T&& > type;
     98        };
    8599        template<> struct add_reference < void >                { typedef void type; };
    86100        template<> struct add_reference < const void >          { typedef void type; };
     
    89103
    90104        template< typename T > struct add_rvalue_reference             { typedef T&& type; };
     105        template< typename T > struct add_rvalue_reference < T& >      { typedef T   type; };
    91106        template<> struct add_rvalue_reference < void >                { typedef void type; };
    92107        template<> struct add_rvalue_reference < const void >          { typedef void type; };
     
    160175        template< typename T > using remove_all_extents_t = typename remove_all_extents<T>::type;
    161176
    162         template < typename T > struct is_lvalue_reference : false_type {};
    163         template < typename T > struct is_lvalue_reference < T& > : true_type{};
    164         template < typename T > struct is_rvalue_reference : false_type {};
    165         template < typename T > struct is_rvalue_reference < T&& > : true_type{};
    166 
    167177        template < typename T >
    168178        typename add_rvalue_reference<T>::type declval();
     
    186196                return static_cast<T&&>( t );
    187197        }
     198
     199        namespace detail
     200        {
     201                template< typename T >
     202                struct addressof_helper
     203                {
     204                        T & value;
     205                        constexpr addressof_helper( T & v ) : value( v ) {}
     206                        constexpr operator T& ( ) const { return value; }
     207                private:
     208                        addressof_helper & operator=( const addressof_helper & );
     209                };
     210
     211                template< typename T >
     212                struct addressof_impl
     213                {
     214                        static constexpr T * f( T & v, long )
     215                        {
     216                                return reinterpret_cast<T*>(
     217                                        &const_cast<char&>( reinterpret_cast<const volatile char &>( v ) ) );
     218                        }
     219                        static constexpr T * f( T * v, int ) { return v; }
     220                };
     221        }
     222
     223        template< typename T >
     224        T * addressof( T & v )
     225        {
     226                return detail::addressof_impl<T>::f( detail::addressof_helper<T>( v ), 0 );
     227        }
     228
     229        namespace detail
     230        {
     231                struct sfinae_types
     232                {
     233                        typedef char size_one;
     234                        typedef struct { char unused[2]; } size_two;
     235                };
     236        }
    188237}
    189238
     239// see unsafe (experimental) version in type_traits experimental.hh
     240#define NV_GENERATE_HAS_TYPE_SAFE( TYPE ) \
     241namespace macro_detail { \
     242template < typename T > class has_##TYPE##_impl : nv::detail::sfinae_types {\
     243  template< typename U > struct wrap_type {}; \
     244  template< typename U > static size_one test( wrap_type< typename U::TYPE >* ); \
     245  template< typename U > static size_two test( ... ); \
     246public:\
     247  static constexpr bool value = sizeof( test<T>(0) ) == 1; \
     248}; } \
     249template < typename T > \
     250struct has_##TYPE : nv::bool_constant< macro_detail::has_##TYPE##_impl< remove_cv_t<T> >::value > {};
     251
    190252#endif // NV_STL_TRAITS_COMMON_HH
  • trunk/nv/stl/type_traits/function.hh

    r385 r389  
    8989        using memfn_class_type_t = typename memfn_class_type<T>::type;
    9090
     91        // Substitute with the solution in type_traits/experimental.hh once
     92        // that one is confirmed safe
     93        NV_GENERATE_HAS_TYPE_SAFE( result_type )
     94
     95        namespace detail
     96        {
     97                template < bool Exists, typename T > struct extract_result_type {};
     98                template < typename T >
     99                struct extract_result_type< true, T >
     100                {
     101                        typedef typename T::result_type result_type;
     102                };
     103
     104                template < typename T >
     105                struct weak_result_type_impl : extract_result_type< has_result_type<T>::value, T > {};
     106
     107// TODO: see if const volatile are needed under MSVC - we remove them after all
     108#if NV_COMPILER == NV_MSVC
     109#define NV_EMIT_WEAK_RESULT_TYPE_CALLDECL( CALLDECL ) \
     110                template < typename R, typename... Args > struct weak_result_type_impl< R CALLDECL( Args... ) > { typedef R result_type; }; \
     111                template < typename R, typename... Args > struct weak_result_type_impl< R( CALLDECL & )( Args... ) > { typedef R result_type; }; \
     112                template < typename R, typename... Args > struct weak_result_type_impl< R( CALLDECL * )( Args... ) > { typedef R result_type; }; \
     113                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( CALLDECL C::* )( Args... ) > { typedef R result_type; }; \
     114                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( CALLDECL C::* )( Args... ) const > { typedef R result_type; }; \
     115                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( CALLDECL C::* )( Args... ) volatile > { typedef R result_type; }; \
     116                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( CALLDECL C::* )( Args... ) const volatile > { typedef R result_type; };
     117
     118NV_EMIT_WEAK_RESULT_TYPE_CALLDECL( __cdecl )
     119NV_EMIT_WEAK_RESULT_TYPE_CALLDECL( __fastcall )
     120NV_EMIT_WEAK_RESULT_TYPE_CALLDECL( __vectorcall )
     121#       if NV_ARCHITECTURE == NV_32BIT
     122NV_EMIT_WEAK_RESULT_TYPE_CALLDECL( __stdcall )
     123template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( __thiscall C::* )( Args... ) > { typedef R result_type; };
     124template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( __thiscall C::* )( Args... ) const > { typedef R result_type; }; \
     125template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( __thiscall C::* )( Args... ) volatile > { typedef R result_type; }; \
     126template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( __thiscall C::* )( Args... ) const volatile > { typedef R result_type; };
     127#       endif
     128#undef NV_EMIT_WEAK_RESULT_TYPE_CALLDECL
     129#else
     130                template < typename R, typename... Args > struct weak_result_type_impl< R( Args... ) > { typedef R result_type; };
     131                template < typename R, typename... Args > struct weak_result_type_impl< R( Args...... ) > { typedef R result_type; };
     132                template < typename R, typename... Args > struct weak_result_type_impl< R( Args... ) const > { typedef R result_type; };
     133                template < typename R, typename... Args > struct weak_result_type_impl< R( Args...... ) const > { typedef R result_type; };
     134                template < typename R, typename... Args > struct weak_result_type_impl< R( Args... ) volatile > { typedef R result_type; };
     135                template < typename R, typename... Args > struct weak_result_type_impl< R( Args...... ) volatile > { typedef R result_type; };
     136                template < typename R, typename... Args > struct weak_result_type_impl< R( Args... ) const volatile > { typedef R result_type; };
     137                template < typename R, typename... Args > struct weak_result_type_impl< R( Args...... ) const volatile > { typedef R result_type; };
     138                template < typename R, typename... Args > struct weak_result_type_impl< R( & )( Args... ) > { typedef R result_type; };
     139                template < typename R, typename... Args > struct weak_result_type_impl< R( & )( Args...... ) > { typedef R result_type; };
     140                template < typename R, typename... Args > struct weak_result_type_impl< R( * )( Args... ) > { typedef R result_type; };
     141                template < typename R, typename... Args > struct weak_result_type_impl< R( * )( Args...... ) > { typedef R result_type; };
     142                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( C::* )( Args... ) > { typedef R result_type; };
     143                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( C::* )( Args...... ) > { typedef R result_type; };
     144                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( C::* )( Args... ) const > { typedef R result_type; };
     145                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( C::* )( Args...... ) const > { typedef R result_type; };
     146                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( C::* )( Args... ) volatile > { typedef R result_type; };
     147                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( C::* )( Args...... ) volatile > { typedef R result_type; };
     148                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( C::* )( Args... ) const volatile > { typedef R result_type; };
     149                template < typename R, typename C, typename... Args > struct weak_result_type_impl< R( C::* )( Args...... ) const volatile > { typedef R result_type; };
     150#endif
     151        }
     152
     153        template < typename T >
     154        struct weak_result_type : detail::weak_result_type_impl< remove_cv_t< T > > {};
     155
     156
    91157}
    92158
  • trunk/nv/stl/type_traits/primary.hh

    r385 r389  
    9797        template < typename F >
    9898        struct is_member_pointer : bool_constant < is_member_function_pointer<F>::value > {};
    99         template < typename C, typename R >
    100         struct is_member_pointer<R C::*> : true_type{};
     99        template < typename C, typename F >
     100        struct is_member_pointer<F C::*> : true_type{};
    101101
    102102        // TODO: check if member functions can actually match under any compiler
  • trunk/nv/stl/type_traits/properties.hh

    r385 r389  
    5252        template < typename T >
    5353        struct is_compound : bool_constant < !is_fundamental< T >::value > {};
    54 
    55         template < typename T >
    56         struct is_reference : bool_constant <
    57                 is_lvalue_reference<T>::value ||
    58                 is_rvalue_reference<T>::value
    59         > {};
    60 
    6154
    6255        // TODO : confirm conformance
  • trunk/nv/stl/type_traits/transforms.hh

    r387 r389  
    1414
    1515#include <nv/core/common.hh>
     16#include <nv/stl/functional/invoke.hh>
    1617#include <nv/stl/type_traits/common.hh>
    1718#include <nv/stl/type_traits/primary.hh>
     
    238239        using common_type_t = typename common_type<Types...>::type;
    239240
    240         namespace detail
    241         {
    242 
    243                 template < typename F, typename... Args >
    244                 inline auto result_call( F&& f, Args&&... args )
    245                         -> decltype( forward<F>( f )( forward<Args>( args )... ) )
    246                 {
    247                         return forward<F>( f )( forward<Args>( args )... );
    248                 }
    249 
    250                 template < typename Base, typename T, typename Derived >
    251                 inline auto result_call( T Base::*pmd, Derived&& ref )
    252                         -> decltype( forward<Derived>( ref ).*pmd )
    253                 {
    254                         return forward<Derived>( ref ).*pmd;
    255                 }
    256 
    257                 template < typename PMD, typename Pointer >
    258                 inline auto result_call( PMD&& pmd, Pointer&& ptr )
    259                         -> decltype( ( *forward<Pointer>( ptr ) ).*forward<PMD>( pmd ) )
    260                 {
    261                         return ( *forward<Pointer>( ptr ) ).*forward<PMD>( pmd );
    262                 }
    263 
    264                 template < typename Base, typename T, typename Derived, typename... Args >
    265                 inline auto result_call( T Base::*pmf, Derived&& ref, Args&&... args )
    266                         -> decltype( ( forward<Derived>( ref ).*pmf )( forward<Args>( args )... ) )
    267                 {
    268                         return ( forward<Derived>( ref ).*pmf )( forward<Args>( args )... );
    269                 }
    270 
    271                 template < typename PMF, typename Pointer, typename... Args >
    272                 inline auto result_call( PMF&& pmf, Pointer&& ptr, Args&&... args )
    273                         -> decltype( ( ( *forward<Pointer>( ptr ) ).*forward<PMF>( pmf ) )( forward<Args>( args )... ) )
    274                 {
    275                         return ( ( *forward<Pointer>( ptr ) ).*forward<PMF>( pmf ) )( forward<Args>( args )... );
    276                 }
    277 
    278                 // TODO: fix this once compiler takes it
    279                 //              template < typename, typename = void >
    280                 //              struct result_of_impl {};
    281                 //
    282                 //              template < typename F, typename...Args >
    283                 //              struct result_of_impl < F( Args... ),
    284                 //                      decltype( void( result_call( declval_i<F>(), declval_i<Args>()... ) ) ) >
    285                 //              {
    286                 //                      using type = decltype( result_call( declval_i<F>(), declval_i<Args>()... ) );
    287                 //              };
    288 
    289                 template < typename > struct result_of_impl;
    290                 template < typename F, typename... Args >
    291                 struct result_of_impl < F( Args... ) >
    292                 {
    293                         using type = decltype( result_call( declval<F>(), declval<Args>()... ) );
    294                 };
    295         }
    296 
    297         template < typename T >
    298         struct result_of : detail::result_of_impl < T > {};
     241        template < typename T >
     242        struct result_of
     243        {
     244                static_assert( static_assert_fail<T>::value, "Failed to get result_of!" );
     245        };
     246
     247
     248#if NV_COMPILER == NV_MSVC
     249        template < typename F, typename... Args >
     250        struct result_of < F __cdecl ( Args... ) > { typedef decltype( invoke( declval<F>(), declval<Args>()... ) ) type; };
     251        template < typename F, typename... Args >
     252        struct result_of < F __fastcall ( Args... ) > { typedef decltype( invoke( declval<F>(), declval<Args>()... ) ) type; };
     253        template < typename F, typename... Args >
     254        struct result_of < F __vectorcall ( Args... ) > { typedef decltype( invoke( declval<F>(), declval<Args>()... ) ) type; };
     255#if NV_ARCHITECTURE == NV_32BIT
     256        template < typename F, typename... Args >
     257        struct result_of < F __stdcall ( Args... ) > { typedef decltype( invoke( declval<F>(), declval<Args>()... ) ) type; };
     258#endif
     259#else
     260        template < typename F, typename... Args >
     261        struct result_of < F( Args... ) > { typedef decltype( invoke( declval<T>(), declval<Args>()... ) ) type; };
     262#endif
     263
    299264
    300265        template < typename T >
    301266        using result_of_t = typename result_of<T>::type;
     267
     268
    302269}
    303270
  • trunk/nv/stl/utility.hh

    r387 r389  
    1616#include <nv/stl/utility/common.hh>
    1717#include <nv/stl/utility/pair.hh>
     18#include <nv/stl/utility/make_pair.hh>
    1819
    1920#endif // NV_STL_UTILITY_HH
  • trunk/nv/stl/utility/pair.hh

    r387 r389  
    2828                constexpr pair() : first(), second() {}
    2929                constexpr pair( const T1& f, const T2& s )
    30                         : first( f ), second( s )
     30                        : first( f ), second( s ) {}
     31                // TODO: this is non-standard, and I dont like it,
     32                // but is used in hash_table. Remove?
     33                constexpr pair( const T1& f )
     34                        : first( f ), second() {}
    3135
    32                         pair( const pair& ) = default;
     36                pair( const pair& ) = default;
    3337                pair( pair&& ) = default;
    3438
  • trunk/src/formats/md3_loader.cc

    r383 r389  
    88
    99#include "nv/core/logging.hh"
    10 #include <cstring>
    1110
    1211using namespace nv;
Note: See TracChangeset for help on using the changeset viewer.