Changeset 359


Ignore:
Timestamp:
04/29/15 18:46:16 (10 years ago)
Author:
epyon
Message:
  • rewrite of lua_path: doesn't use dynamic memory anymore variadic constructor and perfect forwarding leverages string_ref general cleanup
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/lua/lua_path.hh

    r345 r359  
    44// This file is part of NV Libraries.
    55// For conditions of distribution and use, see copyright notice in nv.hh
     6//
     7// TODO : prepare tests:
     8//  * correctness tests
     9//  * compatibility tests
     10//  * performance tests
     11// TODO : resolve should not take a lua_State
    612
    713#ifndef NV_LUA_PATH_HH
     
    1016#include <nv/core/common.hh>
    1117#include <nv/core/string.hh>
     18#include <nv/core/string_ref.hh>
    1219#include <cstring>
    1320
     
    2128                class path
    2229                {
    23                         struct element
     30                public:
     31                        template < typename... Args >
     32                        path( Args&&... args ) : m_count(0)
    2433                        {
    25                                 size_t value;
    26                                 size_t length;
    27                                 element() : value( 0 ), length( 0 ) {}
    28                         };
    29 
    30 
    31                 public:
    32                         path( nv::string p );
    33                         path( const char* p );
    34                         path( unsigned i );
    35 
    36                         template < typename T1, typename T2 >
    37                         path( const T1& p1, const T2& p2 ) : m_count( 0 )
    38                         {
    39                                 const size_t l1 = string_length<T1>::get( p1 );
    40                                 const size_t l2 = string_length<T2>::get( p2 );
    41                                 m_path.reserve( l1 + l2 + 1 );
    42                                 push( p1, l1 );
    43                                 push( p2, l2 );
    44                         }
    45 
    46                         template < typename T1, typename T2, typename T3 >
    47                         path( const T1& p1, const T2& p2, const T3& p3 ) : m_count( 0 )
    48                         {
    49                                 const size_t l1 = string_length<T1>::get( p1 );
    50                                 const size_t l2 = string_length<T2>::get( p2 );
    51                                 const size_t l3 = string_length<T3>::get( p3 );
    52                                 m_path.reserve( l1 + l2 + l3 + 1 );
    53                                 push( p1, l1 );
    54                                 push( p2, l2 );
    55                                 push( p3, l3 );
    56                         }
    57 
    58                         template < typename T1, typename T2, typename T3, typename T4 >
    59                         path( const T1& p1, const T2& p2, const T3& p3, const T4& p4 ) : m_count( 0 )
    60                         {
    61                                 const size_t l1 = string_length<T1>::get( p1 );
    62                                 const size_t l2 = string_length<T2>::get( p2 );
    63                                 const size_t l3 = string_length<T3>::get( p3 );
    64                                 const size_t l4 = string_length<T4>::get( p4 );
    65                                 m_path.reserve( l1 + l2 + l3 + l4 + 1 );
    66                                 push( p1, l1 );
    67                                 push( p2, l2 );
    68                                 push( p3, l3 );
    69                                 push( p4, l4 );
    70                         }
    71 
    72                         template < typename T1, typename T2, typename T3, typename T4, typename T5 >
    73                         path( const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5 ) : m_count( 0 )
    74                         {
    75                                 const size_t l1 = string_length<T1>::get( p1 );
    76                                 const size_t l2 = string_length<T2>::get( p2 );
    77                                 const size_t l3 = string_length<T3>::get( p3 );
    78                                 const size_t l4 = string_length<T4>::get( p4 );
    79                                 const size_t l5 = string_length<T5>::get( p5 );
    80                                 m_path.reserve( l1 + l2 + l3 + l4 + l5 + 1 );
    81                                 push( p1, l1 );
    82                                 push( p2, l2 );
    83                                 push( p3, l3 );
    84                                 push( p4, l4 );
    85                                 push( p4, l5 );
     34                                static_assert( sizeof...( Args ) < 8, "Path can only take up to 8 arguments!" );
     35                                initialize( std::forward<Args>( args )... );
    8636                        }
    8737
    8838                        std::string to_string() const;
    8939                        bool resolve( lua_State* L, bool global = true ) const;
     40               
    9041                private:
     42                        template < typename T >
     43                        void initialize( T&& arg )
     44                        {
     45                                push( std::forward<T>( arg ) );
     46                                if ( m_count == 1 && m_elements[0].length ) parse();
     47                        }
     48
     49                        template < typename T, typename... Args >
     50                        void initialize( T&& arg, Args&&... args )
     51                        {
     52                                push( std::forward<T>( arg ) );
     53                                initialize( std::forward<Args>( args )... );
     54                        }
    9155
    9256                        void parse();
    93                         void push( size_t start, size_t length );
    94                         void push( size_t e );
    95                         void push( const nv::string& p, size_t lenght );
    96                         void push( const char* s, size_t length );
     57                        void push( size_t value );
     58                        void push( string_ref p );
     59
    9760                private:
    98                         element     m_elements[8];
    99                         sint32      m_count;
    100                         std::string m_path;
     61                        struct element
     62                        {
     63                                union
     64                                {
     65                                        size_t      value;
     66                                        const char* str;
     67                                };
     68                                size_t      length;
     69                        };
     70
     71                        element m_elements[8];
     72                        sint32  m_count;
    10173                };
    10274
  • trunk/src/lua/lua_path.cc

    r319 r359  
    1111using namespace nv;
    1212
    13 lua::path::path( nv::string p )
    14         : m_count(0), m_path( std::move( p ) )
     13void lua::path::parse()
    1514{
    16         parse();
     15        if ( m_elements[0].length == 0 || m_elements[0].str == nullptr ) return;
     16        string_ref spath( m_elements[0].str, m_elements[0].length );
     17        m_count = 0;
     18        size_t point = spath.find( '.' );
     19
     20        while ( point != std::string::npos )
     21        {
     22                m_elements[m_count].str    = spath.data();
     23                m_elements[m_count].length = point;
     24                m_count++;
     25                spath.remove_prefix( point + 1 );
     26                point = spath.find( '.' );
     27        }
     28
     29        m_elements[m_count].str    = spath.data();
     30        m_elements[m_count].length = spath.length();
     31        m_count++;
    1732}
    1833
    19 lua::path::path( const char* p )
    20         : m_count(0), m_path( p )
     34void lua::path::push( size_t value )
    2135{
    22         parse();
    23 }
    24 
    25 lua::path::path( unsigned i )
    26         : m_count(0)
    27 {
    28         push( i );
    29 }
    30 
    31 void lua::path::parse()
    32 {
    33         size_t start = 0;
    34         size_t point = m_path.find('.');
    35 
    36         while( point != std::string::npos )
    37         {
    38                 push( start, point-start );
    39                 start = point+1;
    40                 point = m_path.find( '.', start );
    41         }
    42 
    43         push( start, m_path.length() - start );
    44 }
    45 
    46 void lua::path::push( size_t e )
    47 {
    48         m_elements[ m_count ].value  = e;
     36        m_elements[ m_count ].value  = value;
    4937        m_elements[ m_count ].length = 0;
    5038        m_count++;
    5139}
    5240
    53 void lua::path::push( size_t start, size_t length )
     41void nv::lua::path::push( string_ref p )
    5442{
    55         m_elements[ m_count ].value  = start;
    56         m_elements[ m_count ].length = length;
    57         m_count++;
    58 }
    59 
    60 void lua::path::push( const char* p, size_t length )
    61 {
    62         m_elements[ m_count ].value  = m_path.length();
    63         m_elements[ m_count ].length = length;
    64         m_path.append( p, length );
    65         m_count++;
    66 }
    67 
    68 void lua::path::push( const std::string& s, size_t length )
    69 {
    70         m_elements[ m_count ].value  = m_path.length();
    71         m_elements[ m_count ].length = length;
    72         m_path.append( s, 0, length );
     43        m_elements[ m_count ].str    = p.data();
     44        m_elements[ m_count ].length = p.length();
    7345        m_count++;
    7446}
     
    8456                        if ( m_elements[i].length > 0 )
    8557                        {
    86                                 lua_pushlstring( L, m_path.c_str() + m_elements[i].value, m_elements[i].length );
     58                                lua_pushlstring( L, m_elements[i].str, m_elements[i].length );
    8759                        }
    8860                        else
     
    10577{
    10678        std::string result;
    107         result.reserve( 2 * m_path.length() );
     79        result.reserve( 64 );
    10880        bool dot = false;
    10981        for ( const element& e : m_elements )
     
    11789                else
    11890                {
    119                         result.append( m_path, e.value, e.length );
     91                        result.append( e.str, e.length );
    12092                        dot = true;
    12193                }
Note: See TracChangeset for help on using the changeset viewer.