git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59829 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			141 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        wx/anystr.h
 | 
						|
// Purpose:     wxAnyStrPtr class declaration
 | 
						|
// Author:      Vadim Zeitlin
 | 
						|
// Created:     2009-03-23
 | 
						|
// RCS-ID:      $Id$
 | 
						|
// Copyright:   (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
 | 
						|
// Licence:     wxWindows licence
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#ifndef _WX_ANYSTR_H_
 | 
						|
#define _WX_ANYSTR_H_
 | 
						|
 | 
						|
#include "wx/string.h"
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// wxAnyStrPtr
 | 
						|
//
 | 
						|
// Notice that this is an internal and intentionally not documented class. It
 | 
						|
// is only used by wxWidgets itself to ensure compatibility with previous
 | 
						|
// versions and shouldn't be used by user code. When you see a function
 | 
						|
// returning it you should just know that you can treat it as a string pointer.
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
// This is a helper class convertible to either narrow or wide string pointer.
 | 
						|
// It is similar to wxCStrData but, unlike it, can be NULL which is required to
 | 
						|
// represent the return value of wxDateTime::ParseXXX() methods for example.
 | 
						|
//
 | 
						|
// NB: this class is fully inline and so doesn't need to be DLL-exported
 | 
						|
class wxAnyStrPtr
 | 
						|
{
 | 
						|
public:
 | 
						|
    // ctors: this class must be created from the associated string or using
 | 
						|
    // its default ctor for an invalid NULL-like object; notice that it is
 | 
						|
    // immutable after creation.
 | 
						|
 | 
						|
    // ctor for invalid pointer
 | 
						|
    wxAnyStrPtr()
 | 
						|
        : m_str(NULL)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    // ctor for valid pointer into the given string (whose lifetime must be
 | 
						|
    // greater than ours and which should remain constant while we're used)
 | 
						|
    wxAnyStrPtr(const wxString& str, const wxString::const_iterator& iter)
 | 
						|
        : m_str(&str),
 | 
						|
          m_iter(iter)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    // default copy ctor is ok and so is default dtor, in particular we do not
 | 
						|
    // free the string
 | 
						|
 | 
						|
 | 
						|
    // various operators meant to make this class look like a superposition of
 | 
						|
    // char* and wchar_t*
 | 
						|
 | 
						|
    // this one is needed to allow boolean expressions involving these objects,
 | 
						|
    // e.g. "if ( FuncReturningAnyStrPtr() && ... )" (unfortunately using
 | 
						|
    // unspecified_bool_type here wouldn't help with ambiguity between all the
 | 
						|
    // different conversions to pointers)
 | 
						|
    operator bool() const { return m_str != NULL; }
 | 
						|
 | 
						|
    // at least VC6 and VC7 also need this one or they complain about ambiguity
 | 
						|
    // for !anystr expressions
 | 
						|
    bool operator!() const { return !((bool)*this); }
 | 
						|
 | 
						|
 | 
						|
    // and these are the conversions operator which allow to assign the result
 | 
						|
    // of FuncReturningAnyStrPtr() to either char* or wxChar* (i.e. wchar_t*)
 | 
						|
    operator const char *() const
 | 
						|
    {
 | 
						|
        if ( !m_str )
 | 
						|
            return NULL;
 | 
						|
 | 
						|
        // check if the string is convertible to char at all
 | 
						|
        //
 | 
						|
        // notice that this pointer points into wxString internal buffer
 | 
						|
        // containing its char* representation and so it can be kept for as
 | 
						|
        // long as wxString is not modified -- which is long enough for our
 | 
						|
        // needs
 | 
						|
        const char *p = m_str->c_str().AsChar();
 | 
						|
        if ( *p )
 | 
						|
        {
 | 
						|
            // find the offset of the character corresponding to this iterator
 | 
						|
            // position in bytes: we don't have any direct way to do it so we
 | 
						|
            // need to redo the conversion again for the part of the string
 | 
						|
            // before the iterator to find its length in bytes in current
 | 
						|
            // locale
 | 
						|
            //
 | 
						|
            // NB: conversion won't fail as it succeeded for the entire string
 | 
						|
            p += strlen(wxString(m_str->begin(), m_iter).mb_str());
 | 
						|
        }
 | 
						|
        //else: conversion failed, return "" as we can't do anything else
 | 
						|
 | 
						|
        return p;
 | 
						|
    }
 | 
						|
 | 
						|
    operator const wchar_t *() const
 | 
						|
    {
 | 
						|
        if ( !m_str )
 | 
						|
            return NULL;
 | 
						|
 | 
						|
        // no complications with wide strings (as long as we discount
 | 
						|
        // surrogates as we do for now)
 | 
						|
        //
 | 
						|
        // just remember that this works as long as wxString keeps an internal
 | 
						|
        // buffer with its wide wide char representation, just as with AsChar()
 | 
						|
        // above
 | 
						|
        return m_str->c_str().AsWChar() + (m_iter - m_str->begin());
 | 
						|
    }
 | 
						|
 | 
						|
    // Because the objects of this class are only used as return type for
 | 
						|
    // functions which can return NULL we can skip providing dereferencing
 | 
						|
    // operators: the code using this class must test it for NULL first and if
 | 
						|
    // it does anything else with it it has to assign it to either char* or
 | 
						|
    // wchar_t* itself, before dereferencing.
 | 
						|
    //
 | 
						|
    // IOW this
 | 
						|
    //
 | 
						|
    //      if ( *FuncReturningAnyStrPtr() )
 | 
						|
    //
 | 
						|
    // is invalid because it could crash. And this
 | 
						|
    //
 | 
						|
    //      const char *p = FuncReturningAnyStrPtr();
 | 
						|
    //      if ( p && *p )
 | 
						|
    //
 | 
						|
    // already works fine.
 | 
						|
 | 
						|
private:
 | 
						|
    // the original string and the position in it we correspond to, if the
 | 
						|
    // string is NULL this object is NULL pointer-like
 | 
						|
    const wxString * const m_str;
 | 
						|
    const wxString::const_iterator m_iter;
 | 
						|
 | 
						|
    wxDECLARE_NO_ASSIGN_CLASS(wxAnyStrPtr);
 | 
						|
};
 | 
						|
 | 
						|
#endif // _WX_ANYSTR_H_
 | 
						|
 |