SystemPath SystemPath::toRelative( SystemPath const& aBaseSystemPath ) const { // 1. "" (empty) means Model itself, which is invalid for this method. // 2. Not absolute is invalid (not absolute implies not empty). if( ! isAbsolute() || isModel() ) { return *this; } if( ! aBaseSystemPath.isAbsolute() || aBaseSystemPath.isModel() ) { THROW_EXCEPTION( BadSystemPath, "[" + aBaseSystemPath.asString() + "] is not an absolute SystemPath" ); } SystemPath aThisPathCopy; SystemPath const* thisPath; if ( !isCanonicalized() ) { aThisPathCopy = *this; aThisPathCopy.canonicalize(); thisPath = &aThisPathCopy; } else { thisPath = this; } SystemPath aBaseSystemPathCopy; SystemPath const* aCanonicalizedBaseSystemPath; if ( !aBaseSystemPath.isCanonicalized() ) { aCanonicalizedBaseSystemPath = &aBaseSystemPath; } else { aBaseSystemPathCopy = aBaseSystemPath; aBaseSystemPathCopy.canonicalize(); aCanonicalizedBaseSystemPath = &aBaseSystemPathCopy; } SystemPath aRetval; StringVector::const_iterator j( thisPath->theComponents.begin() ), je( thisPath->theComponents.end() ); StringVector::const_iterator i( aCanonicalizedBaseSystemPath->theComponents.begin() ), ie( aCanonicalizedBaseSystemPath->theComponents.end() ); while ( i != ie && j != je ) { String const& aComp( *i ); if ( aComp != *j ) { break; } ++i, ++j; } if ( i != ie ) { while ( i != ie ) { aRetval.theComponents.push_back( ".." ); ++i; } } std::copy( j, je, std::back_inserter( aRetval.theComponents ) ); if ( aRetval.theComponents.empty() ) { aRetval.theComponents.push_back( "." ); } return aRetval; }