diff options
Diffstat (limited to 'o3tl/qa')
-rw-r--r-- | o3tl/qa/compile-temporary.cxx | 25 | ||||
-rw-r--r-- | o3tl/qa/compile-unsafe_downcast.cxx | 32 | ||||
-rw-r--r-- | o3tl/qa/cow_wrapper_clients.cxx | 296 | ||||
-rw-r--r-- | o3tl/qa/cow_wrapper_clients.hxx | 210 | ||||
-rw-r--r-- | o3tl/qa/test-cow_wrapper.cxx | 263 | ||||
-rw-r--r-- | o3tl/qa/test-enumarray.cxx | 46 | ||||
-rw-r--r-- | o3tl/qa/test-lru_map.cxx | 338 | ||||
-rw-r--r-- | o3tl/qa/test-safeint.cxx | 121 | ||||
-rw-r--r-- | o3tl/qa/test-sorted_vector.cxx | 321 | ||||
-rw-r--r-- | o3tl/qa/test-string_view.cxx | 753 | ||||
-rw-r--r-- | o3tl/qa/test-temporary.cxx | 47 | ||||
-rw-r--r-- | o3tl/qa/test-typed_flags.cxx | 71 | ||||
-rw-r--r-- | o3tl/qa/test-unit_conversion.cxx | 883 | ||||
-rw-r--r-- | o3tl/qa/test-vector_pool.cxx | 88 |
14 files changed, 3494 insertions, 0 deletions
diff --git a/o3tl/qa/compile-temporary.cxx b/o3tl/qa/compile-temporary.cxx new file mode 100644 index 0000000000..1d8d84bd5f --- /dev/null +++ b/o3tl/qa/compile-temporary.cxx @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> + +#include <o3tl/temporary.hxx> + +void f(int*); + +int g(); + +void h(int n) +{ + f(&o3tl::temporary(int())); + f(&o3tl::temporary(g())); + f(&o3tl::temporary(n)); // expected-error {{}} expected-note@o3tl/temporary.hxx:* 0+ {{}} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/o3tl/qa/compile-unsafe_downcast.cxx b/o3tl/qa/compile-unsafe_downcast.cxx new file mode 100644 index 0000000000..8471fc250e --- /dev/null +++ b/o3tl/qa/compile-unsafe_downcast.cxx @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> + +#include <o3tl/unsafe_downcast.hxx> // expected-note@o3tl/unsafe_downcast.hxx:* 0+ {{}} + +struct Base +{ + virtual ~Base(); +}; + +struct Derived : Base +{ +}; + +void f(Base* b, Derived* d) +{ + o3tl::unsafe_downcast<Derived*>(b); + o3tl::unsafe_downcast<Derived const*>(b); + o3tl::unsafe_downcast<Derived&>(*b); // expected-error {{}} + o3tl::unsafe_downcast<Derived*>(d); + o3tl::unsafe_downcast<Base*>(d); // expected-error {{}} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/o3tl/qa/cow_wrapper_clients.cxx b/o3tl/qa/cow_wrapper_clients.cxx new file mode 100644 index 0000000000..913165c83c --- /dev/null +++ b/o3tl/qa/cow_wrapper_clients.cxx @@ -0,0 +1,296 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "cow_wrapper_clients.hxx" +#include <rtl/instance.hxx> + +namespace o3tltests { + +class cow_wrapper_client2_impl +{ +public: + cow_wrapper_client2_impl() : mnValue(0) {} + explicit cow_wrapper_client2_impl( int nVal ) : mnValue(nVal) {} + void setValue( int nVal ) { mnValue = nVal; } + int getValue() const { return mnValue; } + + bool operator==( const cow_wrapper_client2_impl& rRHS ) const { return mnValue == rRHS.mnValue; } + bool operator!=( const cow_wrapper_client2_impl& rRHS ) const { return mnValue != rRHS.mnValue; } + bool operator<( const cow_wrapper_client2_impl& rRHS ) const { return mnValue < rRHS.mnValue; } + +private: + int mnValue; +}; + +cow_wrapper_client2::cow_wrapper_client2() : maImpl() +{ +} + +cow_wrapper_client2::cow_wrapper_client2( int nVal ) : + maImpl( cow_wrapper_client2_impl(nVal) ) +{ +} + +cow_wrapper_client2::~cow_wrapper_client2() +{ +} + +cow_wrapper_client2::cow_wrapper_client2( const cow_wrapper_client2& rSrc ) : + maImpl(rSrc.maImpl) +{ +} + +cow_wrapper_client2::cow_wrapper_client2( cow_wrapper_client2&& rSrc ) noexcept : + maImpl( std::move( rSrc.maImpl ) ) +{ +} + +cow_wrapper_client2& cow_wrapper_client2::operator=( const cow_wrapper_client2& rSrc ) +{ + maImpl = rSrc.maImpl; + + return *this; +} + +cow_wrapper_client2& cow_wrapper_client2::operator=(cow_wrapper_client2&& rSrc) noexcept +{ + maImpl = std::move(rSrc.maImpl); + + return *this; +} + +void cow_wrapper_client2::modify( int nVal ) +{ + maImpl->setValue( nVal ); +} + +int cow_wrapper_client2::queryUnmodified() const +{ + return maImpl->getValue(); +} + +void cow_wrapper_client2::makeUnique() +{ + maImpl.make_unique(); +} +bool cow_wrapper_client2::is_unique() const +{ + return maImpl.is_unique(); +} +oslInterlockedCount cow_wrapper_client2::use_count() const +{ + return maImpl.use_count(); +} +void cow_wrapper_client2::swap( cow_wrapper_client2& r ) +{ + o3tl::swap(maImpl, r.maImpl); +} + +bool cow_wrapper_client2::operator==( const cow_wrapper_client2& rRHS ) const +{ + return maImpl == rRHS.maImpl; +} +bool cow_wrapper_client2::operator!=( const cow_wrapper_client2& rRHS ) const +{ + return maImpl != rRHS.maImpl; +} +bool cow_wrapper_client2::operator<( const cow_wrapper_client2& rRHS ) const +{ + return maImpl < rRHS.maImpl; +} + + +cow_wrapper_client3::cow_wrapper_client3() : maImpl() +{ +} + +cow_wrapper_client3::cow_wrapper_client3( int nVal ) : + maImpl( cow_wrapper_client2_impl(nVal) ) +{ +} + +cow_wrapper_client3::~cow_wrapper_client3() +{ +} + +cow_wrapper_client3::cow_wrapper_client3( const cow_wrapper_client3& rSrc ) : + maImpl(rSrc.maImpl) +{ +} + +cow_wrapper_client3::cow_wrapper_client3( cow_wrapper_client3&& rSrc ) noexcept : + maImpl( std::move( rSrc.maImpl ) ) +{ +} + +cow_wrapper_client3& cow_wrapper_client3::operator=( const cow_wrapper_client3& rSrc ) +{ + maImpl = rSrc.maImpl; + + return *this; +} + +cow_wrapper_client3& cow_wrapper_client3::operator=(cow_wrapper_client3&& rSrc) noexcept +{ + maImpl = std::move(rSrc.maImpl); + + return *this; +} + +void cow_wrapper_client3::modify( int nVal ) +{ + maImpl->setValue( nVal ); +} + +int cow_wrapper_client3::queryUnmodified() const +{ + return maImpl->getValue(); +} + +void cow_wrapper_client3::makeUnique() +{ + maImpl.make_unique(); +} +bool cow_wrapper_client3::is_unique() const +{ + return maImpl.is_unique(); +} +oslInterlockedCount cow_wrapper_client3::use_count() const +{ + return maImpl.use_count(); +} +void cow_wrapper_client3::swap( cow_wrapper_client3& r ) +{ + o3tl::swap(maImpl, r.maImpl); +} + +bool cow_wrapper_client3::operator==( const cow_wrapper_client3& rRHS ) const +{ + return maImpl == rRHS.maImpl; +} +bool cow_wrapper_client3::operator!=( const cow_wrapper_client3& rRHS ) const +{ + return maImpl != rRHS.maImpl; +} +bool cow_wrapper_client3::operator<( const cow_wrapper_client3& rRHS ) const +{ + return maImpl < rRHS.maImpl; +} + + +namespace { struct theDefaultClient4 : public rtl::Static< o3tl::cow_wrapper< int >, + theDefaultClient4 > {}; } + +cow_wrapper_client4::cow_wrapper_client4() : + maImpl(theDefaultClient4::get()) +{ +} + +cow_wrapper_client4::cow_wrapper_client4( int nVal ) : + maImpl( nVal ) +{ +} + +cow_wrapper_client4::~cow_wrapper_client4() +{ +} + +cow_wrapper_client4::cow_wrapper_client4( const cow_wrapper_client4& rSrc ) : + maImpl(rSrc.maImpl) +{ +} + +cow_wrapper_client4& cow_wrapper_client4::operator=( const cow_wrapper_client4& rSrc ) +{ + maImpl = rSrc.maImpl; + + return *this; +} + +bool cow_wrapper_client4::is_default() const +{ + return maImpl.same_object(theDefaultClient4::get()); +} + +bool cow_wrapper_client4::operator==( const cow_wrapper_client4& rRHS ) const +{ + return maImpl == rRHS.maImpl; +} +bool cow_wrapper_client4::operator!=( const cow_wrapper_client4& rRHS ) const +{ + return maImpl != rRHS.maImpl; +} +bool cow_wrapper_client4::operator<( const cow_wrapper_client4& rRHS ) const +{ + return maImpl < rRHS.maImpl; +} + +bool BogusRefCountPolicy::s_bShouldIncrement = false; +bool BogusRefCountPolicy::s_bShouldDecrement = false; +sal_uInt32 BogusRefCountPolicy::s_nEndOfScope = 0; + +cow_wrapper_client5::cow_wrapper_client5() : + maImpl() +{ +} + +cow_wrapper_client5::cow_wrapper_client5(int nX) : + maImpl(nX) +{ +} + +cow_wrapper_client5::cow_wrapper_client5( const cow_wrapper_client5& rSrc ) : + maImpl( rSrc.maImpl ) +{ +} + +cow_wrapper_client5::cow_wrapper_client5( cow_wrapper_client5&& rSrc ) noexcept : + maImpl( std::move( rSrc.maImpl ) ) +{ +} + +cow_wrapper_client5::~cow_wrapper_client5() +{ +} + +cow_wrapper_client5& cow_wrapper_client5::operator=( const cow_wrapper_client5& rSrc ) +{ + maImpl = rSrc.maImpl; + + return *this; +} + +cow_wrapper_client5& cow_wrapper_client5::operator=(cow_wrapper_client5&& rSrc) noexcept +{ + maImpl = std::move( rSrc.maImpl ); + + return *this; +} + +bool cow_wrapper_client5::operator==( const cow_wrapper_client5& rSrc ) const { + return maImpl == rSrc.maImpl; +} + +bool cow_wrapper_client5::operator!=( const cow_wrapper_client5& rSrc ) const { + return maImpl != rSrc.maImpl; +} + +} // namespace o3tltests + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/o3tl/qa/cow_wrapper_clients.hxx b/o3tl/qa/cow_wrapper_clients.hxx new file mode 100644 index 0000000000..d0e416c963 --- /dev/null +++ b/o3tl/qa/cow_wrapper_clients.hxx @@ -0,0 +1,210 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX +#define INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX + +#include <o3tl/cow_wrapper.hxx> +#include <assert.h> +#include <iostream> + +/* Definition of Cow_Wrapper_Clients classes */ + +namespace o3tltests { + +/** This is a header and a separate compilation unit on purpose - + cow_wrapper needs destructor, copy constructor and assignment + operator to be outline, when pimpl idiom is used + */ + +/// test non-opaque impl type +class cow_wrapper_client1 +{ +public: + cow_wrapper_client1() : maImpl() {} + explicit cow_wrapper_client1( int nVal ) : maImpl(nVal) {} + + void modify( int nVal ) { *maImpl = nVal; } + int queryUnmodified() const { return *maImpl; } + + void makeUnique() { maImpl.make_unique(); } + bool is_unique() const { return maImpl.is_unique(); } + oslInterlockedCount use_count() const { return maImpl.use_count(); } + void swap( cow_wrapper_client1& r ) { o3tl::swap(maImpl, r.maImpl); } + + bool operator==( const cow_wrapper_client1& rRHS ) const { return maImpl == rRHS.maImpl; } + bool operator!=( const cow_wrapper_client1& rRHS ) const { return maImpl != rRHS.maImpl; } + bool operator<( const cow_wrapper_client1& rRHS ) const { return maImpl < rRHS.maImpl; } + +private: + o3tl::cow_wrapper< int > maImpl; +}; + + +class cow_wrapper_client2_impl; + +/** test opaque impl type - need to explicitly declare lifetime + methods + */ +class cow_wrapper_client2 +{ +public: + cow_wrapper_client2(); + explicit cow_wrapper_client2( int nVal ); + ~cow_wrapper_client2(); + + cow_wrapper_client2( const cow_wrapper_client2& ); + cow_wrapper_client2(cow_wrapper_client2&&) noexcept; + cow_wrapper_client2& operator=( const cow_wrapper_client2& ); + cow_wrapper_client2& operator=(cow_wrapper_client2&&) noexcept; + + void modify( int nVal ); + int queryUnmodified() const; + + void makeUnique(); + bool is_unique() const; + oslInterlockedCount use_count() const; + void swap( cow_wrapper_client2& r ); + + bool operator==( const cow_wrapper_client2& rRHS ) const; + bool operator!=( const cow_wrapper_client2& rRHS ) const; + bool operator<( const cow_wrapper_client2& rRHS ) const; + +private: + o3tl::cow_wrapper< cow_wrapper_client2_impl > maImpl; +}; + +/** test MT-safe cow_wrapper - basically the same as + cow_wrapper_client2, only with different refcounting policy + */ +class cow_wrapper_client3 +{ +public: + cow_wrapper_client3(); + explicit cow_wrapper_client3( int nVal ); + ~cow_wrapper_client3(); + + cow_wrapper_client3( const cow_wrapper_client3& ); + cow_wrapper_client3(cow_wrapper_client3&&) noexcept; + cow_wrapper_client3& operator=( const cow_wrapper_client3& ); + cow_wrapper_client3& operator=(cow_wrapper_client3&&) noexcept; + + void modify( int nVal ); + int queryUnmodified() const; + + void makeUnique(); + bool is_unique() const; + oslInterlockedCount use_count() const; + void swap( cow_wrapper_client3& r ); + + bool operator==( const cow_wrapper_client3& rRHS ) const; + bool operator!=( const cow_wrapper_client3& rRHS ) const; + bool operator<( const cow_wrapper_client3& rRHS ) const; + +private: + o3tl::cow_wrapper< cow_wrapper_client2_impl, o3tl::ThreadSafeRefCountingPolicy > maImpl; +}; + +/** test default-object comparison - have default-stored-client4 share + the same static impl instance, check if isDefault does the right + thing + */ +class cow_wrapper_client4 +{ +public: + cow_wrapper_client4(); + explicit cow_wrapper_client4(int); + ~cow_wrapper_client4(); + + cow_wrapper_client4( const cow_wrapper_client4& ); + cow_wrapper_client4& operator=( const cow_wrapper_client4& ); + + bool is_default() const; + + bool operator==( const cow_wrapper_client4& rRHS ) const; + bool operator!=( const cow_wrapper_client4& rRHS ) const; + bool operator<( const cow_wrapper_client4& rRHS ) const; + +private: + o3tl::cow_wrapper< int > maImpl; +}; + +// singleton ref-counting policy used to keep track of when +// incrementing and decrementing occurs +struct BogusRefCountPolicy +{ + static bool s_bShouldIncrement; + static bool s_bShouldDecrement; + static sal_uInt32 s_nEndOfScope; + typedef sal_uInt32 ref_count_t; + static void incrementCount( ref_count_t& rCount ) { + assert(s_bShouldIncrement && "Ref-counting policy incremented when it should not have."); + ++rCount; + s_bShouldIncrement = false; + } + static bool decrementCount( ref_count_t& rCount ) { + assert((s_nEndOfScope || s_bShouldDecrement) && "Ref-counting policy decremented when it should not have."); + if(s_nEndOfScope) + { + --rCount; + --s_nEndOfScope; + } + else if(s_bShouldDecrement) + { + --rCount; + s_bShouldDecrement = false; + } + return rCount != 0; + } +}; + +class cow_wrapper_client5 +{ +public: + cow_wrapper_client5(); + explicit cow_wrapper_client5(int); + ~cow_wrapper_client5(); + + cow_wrapper_client5( const cow_wrapper_client5& ); + cow_wrapper_client5(cow_wrapper_client5&&) noexcept; + cow_wrapper_client5& operator=( const cow_wrapper_client5& ); + cow_wrapper_client5& operator=(cow_wrapper_client5&&) noexcept; + + int queryUnmodified() const { return *maImpl; } + sal_uInt32 use_count() const { return maImpl.use_count(); } + + bool operator==( const cow_wrapper_client5& rRHS ) const; + bool operator!=( const cow_wrapper_client5& rRHS ) const; + +private: + o3tl::cow_wrapper< int, BogusRefCountPolicy > maImpl; +}; + +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, const cow_wrapper_client5& client ) +{ + return stream << client.queryUnmodified(); +} + +} // namespace o3tltests + +#endif // INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/o3tl/qa/test-cow_wrapper.cxx b/o3tl/qa/test-cow_wrapper.cxx new file mode 100644 index 0000000000..b5d4936d5d --- /dev/null +++ b/o3tl/qa/test-cow_wrapper.cxx @@ -0,0 +1,263 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/types.h> +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> + +#include "cow_wrapper_clients.hxx" + +using namespace ::o3tl; +using namespace ::o3tltests; + + +class cow_wrapper_test : public CppUnit::TestFixture +{ +public: + template< class T > void test( T& rTestObj1, T& rTestObj2, T& rTestObj3 ) + { + CPPUNIT_ASSERT_MESSAGE("rTestObj1 is unique", + rTestObj1.is_unique() ); + CPPUNIT_ASSERT_MESSAGE("rTestObj2 is unique", + rTestObj2.is_unique() ); + CPPUNIT_ASSERT_MESSAGE("rTestObj3 is unique", + rTestObj3.is_unique() ); + + CPPUNIT_ASSERT_MESSAGE("rTestObj1 != rTestObj2", + rTestObj1 != rTestObj2 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj2 != rTestObj3", + rTestObj2 != rTestObj3 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj1 != rTestObj3", + rTestObj1 != rTestObj3 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj1 < rTestObj2", + rTestObj1 < rTestObj2 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj2 < rTestObj3", + rTestObj2 < rTestObj3 ); + + rTestObj2 = rTestObj1; + rTestObj3 = rTestObj1; + CPPUNIT_ASSERT_MESSAGE("rTestObj1 == rTestObj2", + rTestObj1 == rTestObj2 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj1 == rTestObj3", + rTestObj1 == rTestObj3 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj1.use_count() == 3", + rTestObj1.use_count() == 3 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj2.use_count() == 3", + rTestObj2.use_count() == 3 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj3.use_count() == 3", + rTestObj3.use_count() == 3 ); + + rTestObj2.makeUnique(); + CPPUNIT_ASSERT_MESSAGE("rTestObj1 == rTestObj2", + rTestObj1 == rTestObj2 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj1 == rTestObj3", + rTestObj1 == rTestObj3 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj1.use_count() == 2", + rTestObj1.use_count() == 2 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj2.use_count() == 1", + rTestObj2.use_count() == 1 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj2.is_unique()", + rTestObj2.is_unique() ); + CPPUNIT_ASSERT_MESSAGE("rTestObj3.use_count() == 2", + rTestObj3.use_count() == 2 ); + + rTestObj2.swap( rTestObj3 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj1 == rTestObj2", + rTestObj1 == rTestObj2 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj1 == rTestObj3", + rTestObj1 == rTestObj3 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj1.use_count() == 2", + rTestObj1.use_count() == 2 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj2.use_count() == 2", + rTestObj2.use_count() == 2 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj3.use_count() == 1", + rTestObj3.use_count() == 1 ); + CPPUNIT_ASSERT_MESSAGE("rTestObj3.is_unique()", + rTestObj3.is_unique() ); + } + + void testCowWrapper() + { + // setup + cow_wrapper_client1 aTestObj1; + cow_wrapper_client1 aTestObj2; + cow_wrapper_client1 aTestObj3; + + cow_wrapper_client2 aTestObj4; + cow_wrapper_client2 aTestObj5; + cow_wrapper_client2 aTestObj6; + + cow_wrapper_client3 aTestObj7; + cow_wrapper_client3 aTestObj8; + cow_wrapper_client3 aTestObj9; + + { + aTestObj1 = cow_wrapper_client1( 1 ); + CPPUNIT_ASSERT_EQUAL(1, aTestObj1.queryUnmodified()); + aTestObj2.modify( 2 ); + CPPUNIT_ASSERT_EQUAL(2, aTestObj2.queryUnmodified()); + aTestObj3.modify( 3 ); + CPPUNIT_ASSERT_EQUAL(3, aTestObj3.queryUnmodified()); + + aTestObj4 = cow_wrapper_client2( 4 ); + CPPUNIT_ASSERT_EQUAL(4, aTestObj4.queryUnmodified()); + aTestObj5.modify( 5 ); + CPPUNIT_ASSERT_EQUAL(5, aTestObj5.queryUnmodified()); + aTestObj6.modify( 6 ); + CPPUNIT_ASSERT_EQUAL(6, aTestObj6.queryUnmodified()); + + aTestObj7 = cow_wrapper_client3( 7 ); + CPPUNIT_ASSERT_EQUAL(7, aTestObj7.queryUnmodified()); + aTestObj8.modify( 8 ); + CPPUNIT_ASSERT_EQUAL(8, aTestObj8.queryUnmodified()); + aTestObj9.modify( 9 ); + CPPUNIT_ASSERT_EQUAL(9, aTestObj9.queryUnmodified()); + } + // all three temporaries are dead now + + // test + test( aTestObj1, aTestObj2, aTestObj3 ); + test( aTestObj4, aTestObj5, aTestObj6 ); + test( aTestObj7, aTestObj8, aTestObj9 ); + } + + void testStaticDefault() + { + cow_wrapper_client4 aTestObj1; + cow_wrapper_client4 aTestObj2; + cow_wrapper_client4 aTestObj3(4); + + CPPUNIT_ASSERT_MESSAGE("aTestObj1.is_default()", + aTestObj1.is_default() ); + CPPUNIT_ASSERT_MESSAGE("aTestObj2.is_default()", + aTestObj2.is_default() ); + CPPUNIT_ASSERT_MESSAGE("!aTestObj3.is_default()", + !aTestObj3.is_default() ); + aTestObj1 = aTestObj2; + CPPUNIT_ASSERT_MESSAGE("aTestObj1.is_default() #2", + aTestObj1.is_default() ); + CPPUNIT_ASSERT_MESSAGE("aTestObj2.is_default() #2", + aTestObj2.is_default() ); + aTestObj1 = aTestObj3; + CPPUNIT_ASSERT_MESSAGE("!aTestObj1.is_default()", + !aTestObj1.is_default() ); + } + + void testRefCounting() + { + // add scope to ensure appropriate number of calls to + // the reference counting policy have been made + { + // if any incrementing/decrementing occurs a failure + // will occur + cow_wrapper_client5 aTestObj1(1); + cow_wrapper_client5 aTestObj2( std::move( aTestObj1 ) ); + CPPUNIT_ASSERT_EQUAL_MESSAGE("aTestObj2.use_count()", + static_cast<sal_uInt32>(1), aTestObj2.use_count() ); + + // the following should increment + BogusRefCountPolicy::s_bShouldIncrement = true; + cow_wrapper_client5 aTestObj3( aTestObj2 ); + CPPUNIT_ASSERT_MESSAGE("s_bShouldIncrement == 0", + !BogusRefCountPolicy::s_bShouldIncrement ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("aTestObj3.use_count()", + static_cast<sal_uInt32>(2), aTestObj3.use_count() ); + { + cow_wrapper_client5 aTestObj4; + // the following should decrement the lvalue and then increment the rvalue + BogusRefCountPolicy::s_bShouldIncrement = true; + BogusRefCountPolicy::s_bShouldDecrement = true; + aTestObj4 = aTestObj2; + CPPUNIT_ASSERT_MESSAGE("s_bShouldIncrement == 0", + !BogusRefCountPolicy::s_bShouldIncrement ); + CPPUNIT_ASSERT_MESSAGE("s_bShouldDecrement == 0", + !BogusRefCountPolicy::s_bShouldDecrement ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("aTestObj2.use_count()", + static_cast<sal_uInt32>(3), aTestObj2.use_count() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE("aTestObj3.use_count()", + static_cast<sal_uInt32>(3), aTestObj3.use_count() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE("aTestObj4.use_count()", + static_cast<sal_uInt32>(3), aTestObj4.use_count() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE("aTestObj2 == aTestObj3", + aTestObj3, aTestObj2 ); + CPPUNIT_ASSERT_EQUAL_MESSAGE("aTestObj3 == aTestObj4", + aTestObj4, aTestObj3 ); + CPPUNIT_ASSERT_EQUAL_MESSAGE("aTestObj2 == aTestObj4", + aTestObj4, aTestObj2 ); + + // only decrement the lvalue before assignment + BogusRefCountPolicy::s_bShouldDecrement = true; + aTestObj4 = cow_wrapper_client5( 4 ); + CPPUNIT_ASSERT_MESSAGE("s_bShouldIncrement == 0", + !BogusRefCountPolicy::s_bShouldIncrement ); + + // only one call should be made to the ref counting policy's + // decrementing function at the end of the scope + BogusRefCountPolicy::s_bShouldDecrement = true; + } + CPPUNIT_ASSERT_MESSAGE("s_bShouldDecrement == 0", + !BogusRefCountPolicy::s_bShouldDecrement ); + + // self assignment + // aTestObj2 is defunct afterwards, one decrement happens + BogusRefCountPolicy::s_bShouldDecrement = true; + aTestObj3 = std::move( aTestObj2 ); + CPPUNIT_ASSERT_EQUAL_MESSAGE("aTestObj2.use_count()", + static_cast<sal_uInt32>(0), aTestObj2.use_count() ); // NOLINT(bugprone-use-after-move) + CPPUNIT_ASSERT_EQUAL_MESSAGE("aTestObj3.use_count()", + static_cast<sal_uInt32>(1), aTestObj3.use_count() ); + + cow_wrapper_client5 aTestObj5; + + // only decrement the lvalue before assignment + BogusRefCountPolicy::s_bShouldDecrement = true; + aTestObj3 = std::move( aTestObj5 ); + CPPUNIT_ASSERT_MESSAGE("s_bShouldDecrement == 0", + !BogusRefCountPolicy::s_bShouldDecrement); + + // one call should be made to the ref-counting policy's + // decrementing function at the end of the scope. Only + // aTestObj3 still holds a valid instance + BogusRefCountPolicy::s_nEndOfScope = 1; + } + CPPUNIT_ASSERT_EQUAL_MESSAGE("s_EndOfScope", + static_cast<sal_uInt32>(0), BogusRefCountPolicy::s_nEndOfScope ); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(cow_wrapper_test); + CPPUNIT_TEST(testCowWrapper); + CPPUNIT_TEST(testStaticDefault); + CPPUNIT_TEST(testRefCounting); + CPPUNIT_TEST_SUITE_END(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(cow_wrapper_test); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/o3tl/qa/test-enumarray.cxx b/o3tl/qa/test-enumarray.cxx new file mode 100644 index 0000000000..f54a923941 --- /dev/null +++ b/o3tl/qa/test-enumarray.cxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <o3tl/enumarray.hxx> + +namespace { + +class Test: public CppUnit::TestFixture { +private: + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testOperations); + CPPUNIT_TEST_SUITE_END(); + + + void testOperations() { + enum class MyEnum { ONE, TWO, THREE, LAST = THREE }; + o3tl::enumarray<MyEnum, int> aModules; + + aModules[MyEnum::ONE] = 1; + aModules[MyEnum::TWO] = 1; + aModules[MyEnum::THREE] = 1; + + o3tl::enumarray<MyEnum, int> const & rModules = aModules; + + for (auto const & i : rModules) + CPPUNIT_ASSERT_EQUAL( 1, i ); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/o3tl/qa/test-lru_map.cxx b/o3tl/qa/test-lru_map.cxx new file mode 100644 index 0000000000..c99a803b31 --- /dev/null +++ b/o3tl/qa/test-lru_map.cxx @@ -0,0 +1,338 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <o3tl/lru_map.hxx> + +#include <o3tl/hash_combine.hxx> + +using namespace ::o3tl; + +class lru_map_test : public CppUnit::TestFixture +{ +public: + void testBaseUsage(); + void testReplaceKey(); + void testReplaceValue(); + void testLruRemoval(); + void testCustomHash(); + void testRemoveIf(); + void testChangeMaxSize(); + void testCustomItemSize(); + + CPPUNIT_TEST_SUITE(lru_map_test); + CPPUNIT_TEST(testBaseUsage); + CPPUNIT_TEST(testReplaceKey); + CPPUNIT_TEST(testReplaceValue); + CPPUNIT_TEST(testLruRemoval); + CPPUNIT_TEST(testCustomHash); + CPPUNIT_TEST(testRemoveIf); + CPPUNIT_TEST(testChangeMaxSize); + CPPUNIT_TEST(testCustomItemSize); + CPPUNIT_TEST_SUITE_END(); +}; + +void lru_map_test::testBaseUsage() +{ + o3tl::lru_map<int, int> lru(10); + lru.insert(std::make_pair<int, int>(1, 1)); + + std::pair<int, int> pair; + for (int i = 2; i < 7; i++) + { + pair.first = pair.second = i; + lru.insert(pair); + } + + CPPUNIT_ASSERT_EQUAL(size_t(6), lru.size()); + + o3tl::lru_map<int, int>::const_iterator it; + + it = lru.find(2); + CPPUNIT_ASSERT(it != lru.end()); + CPPUNIT_ASSERT_EQUAL(2, it->second); + + it = lru.find(5); + CPPUNIT_ASSERT(it != lru.end()); + CPPUNIT_ASSERT_EQUAL(5, it->second); + + it = lru.find(0); + CPPUNIT_ASSERT(bool(it == lru.end())); +} + +void lru_map_test::testReplaceValue() +{ + o3tl::lru_map<int, int> lru(2); + // check if map is empty + CPPUNIT_ASSERT_EQUAL(size_t(0), lru.size()); + + // check if inserting entry with same key replaces the value + + // inserting new entry + lru.insert(std::make_pair<int, int>(1, 2)); + CPPUNIT_ASSERT_EQUAL(size_t(1), lru.size()); + CPPUNIT_ASSERT_EQUAL(2, lru.find(1)->second); + + // inserting new entry with key that already exists + lru.insert(std::make_pair<int, int>(1, 4)); + CPPUNIT_ASSERT_EQUAL(size_t(1), lru.size()); + CPPUNIT_ASSERT_EQUAL(4, lru.find(1)->second); + + // inserting new entry + lru.insert(std::make_pair<int, int>(2, 200)); + CPPUNIT_ASSERT_EQUAL(size_t(2), lru.size()); + CPPUNIT_ASSERT_EQUAL(4, lru.find(1)->second); + CPPUNIT_ASSERT_EQUAL(200, lru.find(2)->second); + + // check if insert with same key, moves the entry back of the lru queue + + // inserting new entry with key that already exists + lru.insert(std::make_pair<int, int>(1, 6)); + // inserting new entry, lru removed + lru.insert(std::make_pair<int, int>(3, 300)); + + CPPUNIT_ASSERT_EQUAL(size_t(2), lru.size()); + CPPUNIT_ASSERT_EQUAL(6, lru.find(1)->second); + CPPUNIT_ASSERT_EQUAL(300, lru.find(3)->second); +} + +void lru_map_test::testReplaceKey() +{ + o3tl::lru_map<int, int> lru(2); + + // inserting new entry + lru.insert(std::make_pair<int, int>(1, 100)); + CPPUNIT_ASSERT_EQUAL(size_t(1), lru.size()); + CPPUNIT_ASSERT_EQUAL(100, lru.find(1)->second); + CPPUNIT_ASSERT(bool(lru.find(2) == lru.end())); + CPPUNIT_ASSERT(bool(lru.find(3) == lru.end())); + + // inserting new entry + lru.insert(std::make_pair<int, int>(2, 200)); + CPPUNIT_ASSERT_EQUAL(size_t(2), lru.size()); + CPPUNIT_ASSERT_EQUAL(100, lru.find(1)->second); + CPPUNIT_ASSERT_EQUAL(200, lru.find(2)->second); + CPPUNIT_ASSERT(bool(lru.find(3) == lru.end())); + + // inserting new entry, lru entry is removed + lru.insert(std::make_pair<int, int>(3, 300)); + CPPUNIT_ASSERT_EQUAL(size_t(2), lru.size()); + CPPUNIT_ASSERT(bool(lru.find(1) == lru.end())); + CPPUNIT_ASSERT_EQUAL(200, lru.find(2)->second); + CPPUNIT_ASSERT_EQUAL(300, lru.find(3)->second); + + // inserting new entry, lru entry is removed + std::pair<int, int> pair(4, 400); + lru.insert(pair); + CPPUNIT_ASSERT_EQUAL(size_t(2), lru.size()); + CPPUNIT_ASSERT(bool(lru.find(1) == lru.end())); + CPPUNIT_ASSERT(bool(lru.find(2) == lru.end())); + CPPUNIT_ASSERT_EQUAL(300, lru.find(3)->second); + CPPUNIT_ASSERT_EQUAL(400, lru.find(4)->second); +} + +void lru_map_test::testLruRemoval() +{ + o3tl::lru_map<int, int> lru(5); + CPPUNIT_ASSERT_EQUAL(size_t(0), lru.size()); + + // fill up... + lru.insert(std::make_pair<int, int>(1, 100)); + lru.insert(std::make_pair<int, int>(2, 200)); + lru.insert(std::make_pair<int, int>(3, 300)); + lru.insert(std::make_pair<int, int>(4, 400)); + lru.insert(std::make_pair<int, int>(5, 500)); + CPPUNIT_ASSERT_EQUAL(size_t(5), lru.size()); + CPPUNIT_ASSERT_EQUAL(100, lru.find(1)->second); + CPPUNIT_ASSERT_EQUAL(200, lru.find(2)->second); + CPPUNIT_ASSERT_EQUAL(300, lru.find(3)->second); + CPPUNIT_ASSERT_EQUAL(400, lru.find(4)->second); + CPPUNIT_ASSERT_EQUAL(500, lru.find(5)->second); + + // add one more entry - lru entry should be removed + lru.insert(std::make_pair<int, int>(6, 600)); + + CPPUNIT_ASSERT_EQUAL(size_t(5), lru.size()); + CPPUNIT_ASSERT_EQUAL(200, lru.find(2)->second); + CPPUNIT_ASSERT_EQUAL(300, lru.find(3)->second); + CPPUNIT_ASSERT_EQUAL(400, lru.find(4)->second); + CPPUNIT_ASSERT_EQUAL(500, lru.find(5)->second); + CPPUNIT_ASSERT_EQUAL(600, lru.find(6)->second); + + // access the lru entry to put it at the back of the lru queue + lru.find(2); + // add new entry - lru entry should be removed + lru.insert(std::make_pair<int, int>(7, 700)); + + CPPUNIT_ASSERT_EQUAL(size_t(5), lru.size()); + CPPUNIT_ASSERT_EQUAL(200, lru.find(2)->second); + CPPUNIT_ASSERT_EQUAL(400, lru.find(4)->second); + CPPUNIT_ASSERT_EQUAL(500, lru.find(5)->second); + CPPUNIT_ASSERT_EQUAL(600, lru.find(6)->second); + CPPUNIT_ASSERT_EQUAL(700, lru.find(7)->second); +} + +namespace +{ +struct TestClassKey +{ + int mA; + int mB; + + TestClassKey(int a, int b) + : mA(a) + , mB(b) + { + } + + bool operator==(TestClassKey const& aOther) const { return mA == aOther.mA && mB == aOther.mB; } +}; + +struct TestClassKeyHashFunction +{ + std::size_t operator()(TestClassKey const& aKey) const + { + std::size_t seed = 0; + o3tl::hash_combine(seed, aKey.mA); + o3tl::hash_combine(seed, aKey.mB); + return seed; + } +}; +} + +void lru_map_test::testCustomHash() +{ + // check lru_map with custom hash function + o3tl::lru_map<TestClassKey, int, TestClassKeyHashFunction> lru(2); + CPPUNIT_ASSERT_EQUAL(size_t(0), lru.size()); + + lru.insert(std::make_pair<TestClassKey, int>(TestClassKey(1, 1), 2)); + CPPUNIT_ASSERT_EQUAL(size_t(1), lru.size()); + + lru.insert(std::make_pair<TestClassKey, int>(TestClassKey(1, 1), 7)); + CPPUNIT_ASSERT_EQUAL(size_t(1), lru.size()); + + lru.insert(std::make_pair<TestClassKey, int>(TestClassKey(1, 2), 9)); + CPPUNIT_ASSERT_EQUAL(size_t(2), lru.size()); + + CPPUNIT_ASSERT(bool(lru.end() == lru.find(TestClassKey(0, 0)))); // non existent + CPPUNIT_ASSERT_EQUAL(7, lru.find(TestClassKey(1, 1))->second); + CPPUNIT_ASSERT_EQUAL(9, lru.find(TestClassKey(1, 2))->second); + + lru.insert(std::make_pair<TestClassKey, int>(TestClassKey(2, 1), 13)); + + CPPUNIT_ASSERT_EQUAL(size_t(2), lru.size()); + + CPPUNIT_ASSERT(bool(lru.end() == lru.find(TestClassKey(1, 1)))); + CPPUNIT_ASSERT_EQUAL(9, lru.find(TestClassKey(1, 2))->second); + CPPUNIT_ASSERT_EQUAL(13, lru.find(TestClassKey(2, 1))->second); +} + +void lru_map_test::testRemoveIf() +{ + typedef o3tl::lru_map<int, int> IntMap; + typedef IntMap::key_value_pair_t IntMapPair; + struct limit_except : public std::exception + { + }; + + IntMap lru(6); + int i = 0; + for (; i < 8; i++) + lru.insert({ i, i }); + CPPUNIT_ASSERT_EQUAL(size_t(6), lru.size()); + // now contains 7..2 + + // remove everything < 4 from the back + try + { + lru.remove_if([](IntMapPair const& rPair) { + if (rPair.first >= 4) + throw limit_except(); + return true; + }); + CPPUNIT_ASSERT(false); // not reached + } + catch (limit_except&) + { + // contains 7..4 + CPPUNIT_ASSERT_EQUAL(size_t(4), lru.size()); + } + + // remove all even numbers + lru.remove_if([](IntMapPair const& rPair) { return (0 == rPair.first % 2); }); + CPPUNIT_ASSERT_EQUAL(size_t(2), lru.size()); + // contains 7, 5 + + lru.insert({ 5, 5 }); + // contains 5, 7 + + i = 5; + for (auto& rPair : lru) + { + CPPUNIT_ASSERT_EQUAL(i, rPair.first); + i += 2; + } + + // remove the first item + lru.remove_if([](IntMapPair const& rPair) { return (rPair.first == 5); }); + CPPUNIT_ASSERT_EQUAL(size_t(1), lru.size()); + + // remove the only item + lru.remove_if([](IntMapPair const& rPair) { return (rPair.first == 7); }); + CPPUNIT_ASSERT_EQUAL(size_t(0), lru.size()); +} + +void lru_map_test::testChangeMaxSize() +{ + o3tl::lru_map<int, int> lru(3); + CPPUNIT_ASSERT_EQUAL(size_t(0), lru.size()); + lru.insert({ 0, 0 }); + lru.insert({ 1, 1 }); + lru.insert({ 2, 2 }); + CPPUNIT_ASSERT_EQUAL(size_t(3), lru.size()); + lru.setMaxSize(1); + CPPUNIT_ASSERT_EQUAL(size_t(1), lru.size()); +} + +void lru_map_test::testCustomItemSize() +{ + struct cost_is_value + { + size_t operator()(int i) { return i; }; + }; + o3tl::lru_map<int, int, std::hash<int>, std::equal_to<int>, cost_is_value> lru(5); + lru.insert({ 1, 1 }); + lru.insert({ 2, 2 }); + // Adding this one will remove the first one, since then the total + // cost would be 6, more than the maximum 5. + lru.insert({ 3, 3 }); + CPPUNIT_ASSERT_EQUAL(size_t(2), lru.size()); + CPPUNIT_ASSERT_EQUAL(size_t(5), lru.total_size()); + // Drop the last item. + lru.remove_if([](std::pair<int, int> i) { return i.first == 3; }); + CPPUNIT_ASSERT_EQUAL(size_t(1), lru.size()); + CPPUNIT_ASSERT_EQUAL(size_t(2), lru.total_size()); + // This should drop everything except for keeping this one (an exception that + // keeps the last item inserted regardless of limit). + lru.insert({ 4, 4 }); + CPPUNIT_ASSERT_EQUAL(size_t(1), lru.size()); + CPPUNIT_ASSERT_EQUAL(size_t(4), lru.total_size()); + lru.clear(); + CPPUNIT_ASSERT_EQUAL(size_t(0), lru.size()); + CPPUNIT_ASSERT_EQUAL(size_t(0), lru.total_size()); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(lru_map_test); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/o3tl/qa/test-safeint.cxx b/o3tl/qa/test-safeint.cxx new file mode 100644 index 0000000000..4c4333082f --- /dev/null +++ b/o3tl/qa/test-safeint.cxx @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> + +#include <limits> + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <o3tl/safeint.hxx> + +namespace +{ +class Test : public CppUnit::TestFixture +{ +private: + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testSignedSaturatingAdd); + CPPUNIT_TEST(testUnsignedSaturatingAdd); + CPPUNIT_TEST_SUITE_END(); + + void testSignedSaturatingAdd() + { + auto const min = std::numeric_limits<int>::min(); + auto const max = std::numeric_limits<int>::max(); + + CPPUNIT_ASSERT_EQUAL(min, o3tl::saturating_add(min, min)); + CPPUNIT_ASSERT_EQUAL(min, o3tl::saturating_add(min, min + 1)); + CPPUNIT_ASSERT_EQUAL(min, o3tl::saturating_add(min, -1)); + CPPUNIT_ASSERT_EQUAL(min, o3tl::saturating_add(min, 0)); + CPPUNIT_ASSERT_EQUAL(min + 1, o3tl::saturating_add(min, 1)); + CPPUNIT_ASSERT_EQUAL(min + max - 1, o3tl::saturating_add(min, max - 1)); + CPPUNIT_ASSERT_EQUAL(min + max, o3tl::saturating_add(min, max)); + + CPPUNIT_ASSERT_EQUAL(min, o3tl::saturating_add(min + 1, min)); + CPPUNIT_ASSERT_EQUAL(min, o3tl::saturating_add(min + 1, min + 1)); + CPPUNIT_ASSERT_EQUAL(min, o3tl::saturating_add(min + 1, -1)); + CPPUNIT_ASSERT_EQUAL(min + 1, o3tl::saturating_add(min + 1, 0)); + CPPUNIT_ASSERT_EQUAL(min + 2, o3tl::saturating_add(min + 1, 1)); + CPPUNIT_ASSERT_EQUAL(min + max, o3tl::saturating_add(min + 1, max - 1)); + CPPUNIT_ASSERT_EQUAL(min + max + 1, o3tl::saturating_add(min + 1, max)); + + CPPUNIT_ASSERT_EQUAL(min, o3tl::saturating_add(-1, min)); + CPPUNIT_ASSERT_EQUAL(min, o3tl::saturating_add(-1, min + 1)); + CPPUNIT_ASSERT_EQUAL(-2, o3tl::saturating_add(-1, -1)); + CPPUNIT_ASSERT_EQUAL(-1, o3tl::saturating_add(-1, 0)); + CPPUNIT_ASSERT_EQUAL(0, o3tl::saturating_add(-1, 1)); + CPPUNIT_ASSERT_EQUAL(max - 2, o3tl::saturating_add(-1, max - 1)); + CPPUNIT_ASSERT_EQUAL(max - 1, o3tl::saturating_add(-1, max)); + + CPPUNIT_ASSERT_EQUAL(min, o3tl::saturating_add(0, min)); + CPPUNIT_ASSERT_EQUAL(min + 1, o3tl::saturating_add(0, min + 1)); + CPPUNIT_ASSERT_EQUAL(-1, o3tl::saturating_add(0, -1)); + CPPUNIT_ASSERT_EQUAL(0, o3tl::saturating_add(0, 0)); + CPPUNIT_ASSERT_EQUAL(1, o3tl::saturating_add(0, 1)); + CPPUNIT_ASSERT_EQUAL(max - 1, o3tl::saturating_add(0, max - 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(0, max)); + + CPPUNIT_ASSERT_EQUAL(min + 1, o3tl::saturating_add(1, min)); + CPPUNIT_ASSERT_EQUAL(min + 2, o3tl::saturating_add(1, min + 1)); + CPPUNIT_ASSERT_EQUAL(0, o3tl::saturating_add(1, -1)); + CPPUNIT_ASSERT_EQUAL(1, o3tl::saturating_add(1, 0)); + CPPUNIT_ASSERT_EQUAL(2, o3tl::saturating_add(1, 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(1, max - 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(1, max)); + + CPPUNIT_ASSERT_EQUAL(min + max - 1, o3tl::saturating_add(max - 1, min)); + CPPUNIT_ASSERT_EQUAL(min + max, o3tl::saturating_add(max - 1, min + 1)); + CPPUNIT_ASSERT_EQUAL(max - 2, o3tl::saturating_add(max - 1, -1)); + CPPUNIT_ASSERT_EQUAL(max - 1, o3tl::saturating_add(max - 1, 0)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max - 1, 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max - 1, max - 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max - 1, max)); + + CPPUNIT_ASSERT_EQUAL(min + max, o3tl::saturating_add(max, min)); + CPPUNIT_ASSERT_EQUAL(min + max + 1, o3tl::saturating_add(max, min + 1)); + CPPUNIT_ASSERT_EQUAL(max - 1, o3tl::saturating_add(max, -1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max, 0)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max, 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max, max - 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max, max)); + } + + void testUnsignedSaturatingAdd() + { + auto const max = std::numeric_limits<unsigned int>::max(); + + CPPUNIT_ASSERT_EQUAL(0U, o3tl::saturating_add(0U, 0U)); + CPPUNIT_ASSERT_EQUAL(1U, o3tl::saturating_add(0U, 1U)); + CPPUNIT_ASSERT_EQUAL(max - 1, o3tl::saturating_add(0U, max - 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(0U, max)); + + CPPUNIT_ASSERT_EQUAL(1U, o3tl::saturating_add(1U, 0U)); + CPPUNIT_ASSERT_EQUAL(2U, o3tl::saturating_add(1U, 1U)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(1U, max - 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(1U, max)); + + CPPUNIT_ASSERT_EQUAL(max - 1, o3tl::saturating_add(max - 1, 0U)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max - 1, 1U)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max - 1, max - 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max - 1, max)); + + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max, 0U)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max, 1U)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max, max - 1)); + CPPUNIT_ASSERT_EQUAL(max, o3tl::saturating_add(max, max)); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/o3tl/qa/test-sorted_vector.cxx b/o3tl/qa/test-sorted_vector.cxx new file mode 100644 index 0000000000..c7fdb0c045 --- /dev/null +++ b/o3tl/qa/test-sorted_vector.cxx @@ -0,0 +1,321 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <memory> +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <o3tl/sorted_vector.hxx> +#include <rtl/ustring.hxx> + +using namespace ::o3tl; + +namespace { + +// helper class +class SwContent +{ +public: + int x; + + explicit SwContent(int x_) : x(x_) {} + + bool operator<( const SwContent &rCmp) const + { + return x < rCmp.x; + } +}; + +} + +class sorted_vector_test : public CppUnit::TestFixture +{ +public: + void testBasics() + { + o3tl::sorted_vector<SwContent*, o3tl::less_ptr_to<SwContent> > aVec; + + // create 4 test elements + std::unique_ptr<SwContent> p1( new SwContent(1) ); + std::unique_ptr<SwContent> p2( new SwContent(2) ); + SwContent *p3 = new SwContent(3); + std::unique_ptr<SwContent> p4( new SwContent(4) ); + + // insert p3, p1 -> not present -> second is true + CPPUNIT_ASSERT( aVec.insert(p3).second ); + CPPUNIT_ASSERT( aVec.insert(p1.get()).second ); + // insert p3 again -> already present -> second is false + CPPUNIT_ASSERT( !aVec.insert(p3).second ); + + // 2 element should be present + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(2), aVec.size() ); + + // check the order -> should be p1, p3 + // by index access + CPPUNIT_ASSERT_EQUAL( p1.get(), aVec[0] ); + CPPUNIT_ASSERT_EQUAL( p3, aVec[1] ); + // by begin, end + CPPUNIT_ASSERT_EQUAL( p1.get(), *aVec.begin() ); + CPPUNIT_ASSERT_EQUAL( p3, *(aVec.end()-1) ); + // by front, back + CPPUNIT_ASSERT_EQUAL( p1.get(), aVec.front() ); + CPPUNIT_ASSERT_EQUAL( p3, aVec.back() ); + + // find elements + CPPUNIT_ASSERT( aVec.find(p1.get()) != aVec.end() ); + CPPUNIT_ASSERT_EQUAL( static_cast<std::ptrdiff_t>(0), aVec.find(p1.get()) - aVec.begin() ); + CPPUNIT_ASSERT( aVec.find(p3) != aVec.end() ); + CPPUNIT_ASSERT_EQUAL( static_cast<std::ptrdiff_t>(1), aVec.find(p3) - aVec.begin() ); + CPPUNIT_ASSERT( bool(aVec.find(p2.get()) == aVec.end()) ); + CPPUNIT_ASSERT( bool(aVec.find(p4.get()) == aVec.end()) ); + + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(1), aVec.erase(p1.get()) ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(1), aVec.size() ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), aVec.erase(p2.get()) ); + + aVec.DeleteAndDestroyAll(); + } + + void testErase() + { + o3tl::sorted_vector<SwContent*, o3tl::less_ptr_to<SwContent> > aVec; + SwContent *p1 = new SwContent(1); + SwContent *p2 = new SwContent(2); + SwContent *p3 = new SwContent(3); + std::unique_ptr<SwContent> p4( new SwContent(4) ); + + aVec.insert(p1); + aVec.insert(p2); + aVec.insert(p3); + + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(1), aVec.erase(p1) ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(2), aVec.size() ); + + aVec.erase_at(1); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(1), aVec.size() ); + + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), aVec.erase(p4.get()) ); + + aVec.clear(); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), aVec.size() ); + + aVec.insert(p1); + aVec.insert(p2); + aVec.insert(p3); + aVec.DeleteAndDestroyAll(); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), aVec.size() ); + } + + void testInsertRange() + { + o3tl::sorted_vector<SwContent*, o3tl::less_ptr_to<SwContent> > aVec1; + std::unique_ptr<SwContent> p1( new SwContent(1) ); + std::unique_ptr<SwContent> p2( new SwContent(2) ); + std::unique_ptr<SwContent> p3( new SwContent(3) ); + + aVec1.insert(p1.get()); + aVec1.insert(p2.get()); + aVec1.insert(p3.get()); + + o3tl::sorted_vector<SwContent*, o3tl::less_ptr_to<SwContent> > aVec2; + aVec2.insert( aVec1 ); + + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(3), aVec2.size() ); + } + + void testLowerBound() + { + o3tl::sorted_vector<SwContent*, o3tl::less_ptr_to<SwContent> > aVec; + std::unique_ptr<SwContent> p1( new SwContent(1) ); + std::unique_ptr<SwContent> p2( new SwContent(2) ); + std::unique_ptr<SwContent> p3( new SwContent(3) ); + std::unique_ptr<SwContent> p4( new SwContent(4) ); + + aVec.insert(p1.get()); + aVec.insert(p2.get()); + aVec.insert(p3.get()); + + CPPUNIT_ASSERT( bool(aVec.lower_bound(p1.get()) == aVec.begin()) ); + CPPUNIT_ASSERT( bool(aVec.lower_bound(p4.get()) == aVec.end()) ); + } + + void testBasics_FindPtr() + { + o3tl::sorted_vector<SwContent*, o3tl::less_ptr_to<SwContent>, + o3tl::find_partialorder_ptrequals> aVec; + std::unique_ptr<SwContent> p1( new SwContent(1) ); + std::unique_ptr<SwContent> p2( new SwContent(2) ); + SwContent *p2_2 = new SwContent(2); + std::unique_ptr<SwContent> p2_3( new SwContent(2) ); + SwContent *p2_4 = new SwContent(2); + SwContent *p3 = new SwContent(3); + std::unique_ptr<SwContent> p4( new SwContent(4) ); + + CPPUNIT_ASSERT( aVec.insert(p3).second ); + CPPUNIT_ASSERT( aVec.insert(p1.get()).second ); + CPPUNIT_ASSERT( !aVec.insert(p3).second ); + + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(2), aVec.size() ); + + CPPUNIT_ASSERT_EQUAL( p1.get(), aVec[0] ); + CPPUNIT_ASSERT_EQUAL( p3, aVec[1] ); + + CPPUNIT_ASSERT( aVec.insert(p2_2).second ); + CPPUNIT_ASSERT( aVec.insert(p2_3.get()).second ); + CPPUNIT_ASSERT( !aVec.insert(p2_2).second ); + CPPUNIT_ASSERT( aVec.insert(p2_4).second ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(5), aVec.size() ); + + CPPUNIT_ASSERT_EQUAL( p1.get(), *aVec.begin() ); + CPPUNIT_ASSERT_EQUAL( p3, *(aVec.end()-1) ); + + CPPUNIT_ASSERT_EQUAL( p1.get(), aVec.front() ); + CPPUNIT_ASSERT_EQUAL( p3, aVec.back() ); + + CPPUNIT_ASSERT( aVec.find(p1.get()) != aVec.end() ); + CPPUNIT_ASSERT_EQUAL( static_cast<std::ptrdiff_t>(0), aVec.find(p1.get()) - aVec.begin() ); + CPPUNIT_ASSERT( aVec.find(p3) != aVec.end() ); + CPPUNIT_ASSERT_EQUAL( static_cast<std::ptrdiff_t>(4), aVec.find(p3) - aVec.begin() ); + CPPUNIT_ASSERT( bool(aVec.find(p2.get()) == aVec.end()) ); + CPPUNIT_ASSERT( bool(aVec.find(p4.get()) == aVec.end()) ); + CPPUNIT_ASSERT( aVec.find(p2_2) != aVec.end() ); + CPPUNIT_ASSERT( aVec.find(p2_2) - aVec.begin() >= 1 ); + CPPUNIT_ASSERT( aVec.find(p2_2) - aVec.begin() < 4 ); + CPPUNIT_ASSERT( aVec.find(p2_3.get()) != aVec.end() ); + CPPUNIT_ASSERT( aVec.find(p2_3.get()) - aVec.begin() >= 1 ); + CPPUNIT_ASSERT( aVec.find(p2_3.get()) - aVec.begin() < 4 ); + CPPUNIT_ASSERT( aVec.find(p2_4) != aVec.end() ); + CPPUNIT_ASSERT( aVec.find(p2_4) - aVec.begin() >= 1 ); + CPPUNIT_ASSERT( aVec.find(p2_4) - aVec.begin() < 4 ); + + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(1), aVec.erase(p1.get()) ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(4), aVec.size() ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), aVec.erase(p2.get()) ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(1), aVec.erase(p2_3.get()) ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(3), aVec.size() ); + + aVec.DeleteAndDestroyAll(); + } + + void testErase_FindPtr() + { + o3tl::sorted_vector<SwContent*, o3tl::less_ptr_to<SwContent>, + o3tl::find_partialorder_ptrequals> aVec; + std::unique_ptr<SwContent> p1( new SwContent(1) ); + SwContent *p1_2 = new SwContent(1); + std::unique_ptr<SwContent> p1_3( new SwContent(1) ); + SwContent *p2 = new SwContent(2); + SwContent *p3 = new SwContent(3); + std::unique_ptr<SwContent> p4( new SwContent(4) ); + + aVec.insert(p1.get()); + aVec.insert(p2); + aVec.insert(p3); + + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(1), aVec.erase(p1.get()) ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(2), aVec.size() ); + + aVec.erase_at(1); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(1), aVec.size() ); + + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), aVec.erase(p4.get()) ); + + aVec.clear(); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), aVec.size() ); + + aVec.insert(p1.get()); + aVec.insert(p2); + aVec.insert(p3); + aVec.insert(p1_2); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(4), aVec.size() ); + aVec.insert(p1_3.get()); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(5), aVec.size() ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(1), aVec.erase(p1.get()) ); + CPPUNIT_ASSERT( bool(aVec.find(p1.get()) == aVec.end()) ); + CPPUNIT_ASSERT( aVec.find(p1_2) != aVec.end() ); + CPPUNIT_ASSERT( aVec.find(p1_3.get()) != aVec.end() ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(1), aVec.erase(p1_3.get()) ); + CPPUNIT_ASSERT( bool(aVec.find(p1.get()) == aVec.end()) ); + CPPUNIT_ASSERT( aVec.find(p1_2) != aVec.end() ); + CPPUNIT_ASSERT( bool(aVec.find(p1_3.get()) == aVec.end()) ); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), aVec.erase(p1_3.get()) ); + CPPUNIT_ASSERT( bool(aVec.find(p1.get()) == aVec.end()) ); + CPPUNIT_ASSERT( aVec.find(p1_2) != aVec.end() ); + CPPUNIT_ASSERT( bool(aVec.find(p1_3.get()) == aVec.end()) ); + + aVec.DeleteAndDestroyAll(); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), aVec.size() ); + } + + void testUniquePtr1() + { + o3tl::sorted_vector<std::unique_ptr<OUString>, o3tl::less_uniqueptr_to<OUString>> aVec; + + auto str_c = aVec.insert(std::make_unique<OUString>("c")).first->get(); + auto str_b1 = aVec.insert(std::make_unique<OUString>("b")).first->get(); + CPPUNIT_ASSERT(!aVec.insert(std::make_unique<OUString>("b")).second); + aVec.insert(std::make_unique<OUString>("a")); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(3), aVec.size() ); + CPPUNIT_ASSERT_EQUAL( OUString("a"), *aVec[0] ); + CPPUNIT_ASSERT_EQUAL( OUString("b"), *aVec[1] ); + CPPUNIT_ASSERT_EQUAL( OUString("c"), *aVec[2] ); + + CPPUNIT_ASSERT( aVec.find(str_c) != aVec.end() ); + CPPUNIT_ASSERT( aVec.find(str_b1) != aVec.end() ); + + OUString tmp("b"); + CPPUNIT_ASSERT( aVec.find(&tmp) != aVec.end() ); + OUString tmp2("z"); + CPPUNIT_ASSERT( bool(aVec.find(&tmp2) == aVec.end()) ); + } + + void testUniquePtr2() + { + o3tl::sorted_vector<std::unique_ptr<OUString>, o3tl::less_uniqueptr_to<OUString>, + o3tl::find_partialorder_ptrequals> aVec; + + auto str_c = aVec.insert(std::make_unique<OUString>("c")).first->get(); + auto str_b1 = aVec.insert(std::make_unique<OUString>("b")).first->get(); + auto str_b2 = aVec.insert(std::make_unique<OUString>("b")).first->get(); + aVec.insert(std::make_unique<OUString>("a")); + CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(4), aVec.size() ); + CPPUNIT_ASSERT_EQUAL( OUString("a"), *aVec[0] ); + CPPUNIT_ASSERT_EQUAL( OUString("b"), *aVec[1] ); + CPPUNIT_ASSERT_EQUAL( OUString("b"), *aVec[2] ); + CPPUNIT_ASSERT_EQUAL( OUString("c"), *aVec[3] ); + + CPPUNIT_ASSERT( aVec.find(str_c) != aVec.end() ); + CPPUNIT_ASSERT( aVec.find(str_b1) != aVec.end() ); + CPPUNIT_ASSERT( aVec.find(str_b2) != aVec.end() ); + + OUString tmp2("z"); + CPPUNIT_ASSERT( bool(aVec.find(&tmp2) == aVec.end()) ); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(sorted_vector_test); + CPPUNIT_TEST(testBasics); + CPPUNIT_TEST(testErase); + CPPUNIT_TEST(testInsertRange); + CPPUNIT_TEST(testLowerBound); + CPPUNIT_TEST(testBasics_FindPtr); + CPPUNIT_TEST(testErase_FindPtr); + CPPUNIT_TEST(testUniquePtr1); + CPPUNIT_TEST(testUniquePtr2); + CPPUNIT_TEST_SUITE_END(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(sorted_vector_test); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/o3tl/qa/test-string_view.cxx b/o3tl/qa/test-string_view.cxx new file mode 100644 index 0000000000..f32537aa35 --- /dev/null +++ b/o3tl/qa/test-string_view.cxx @@ -0,0 +1,753 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> + +#include <string_view> + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <o3tl/safeint.hxx> +#include <o3tl/string_view.hxx> +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> + +template <> +inline std::string +CppUnit::assertion_traits<std::u16string_view>::toString(std::u16string_view const& x) +{ + return std::string(OUStringToOString(x, RTL_TEXTENCODING_UTF8)); +} + +namespace +{ +OString ostringEmpty() { return {}; } // avoid loplugin:stringview +OString ostringDoof() { return "doof"_ostr; } // avoid loplugin:stringview +OString ostringFoo() { return "foo"_ostr; } // avoid loplugin:stringview +OString ostringFoobars() { return "foobars"_ostr; } // avoid loplugin:stringview +OString ostringFood() { return "food"_ostr; } // avoid loplugin:stringview +OString ostringOof() { return "oof"_ostr; } // avoid loplugin:stringview +OString ostringSraboof() { return "sraboof"_ostr; } // avoid loplugin:stringview +OUString oustringEmpty() { return {}; } // avoid loplugin:stringview +OUString oustringDoof() { return "doof"; } // avoid loplugin:stringview +OUString oustringFoo() { return "foo"; } // avoid loplugin:stringview +OUString oustringFoobars() { return "foobars"; } // avoid loplugin:stringview +OUString oustringFood() { return "food"; } // avoid loplugin:stringview +OUString oustringOof() { return "oof"; } // avoid loplugin:stringview +OUString oustringSraboof() { return "sraboof"; } // avoid loplugin:stringview + +class Test : public CppUnit::TestFixture +{ +private: + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testStartsWith); + CPPUNIT_TEST(testStartsWithRest); + CPPUNIT_TEST(testEndsWith); + CPPUNIT_TEST(testEndsWithRest); + CPPUNIT_TEST(testEqualsIgnoreAsciiCase); + CPPUNIT_TEST(testGetToken); + CPPUNIT_TEST(testIterateCodePoints); + CPPUNIT_TEST_SUITE_END(); + + void testStartsWith() + { + using namespace std::string_view_literals; + CPPUNIT_ASSERT(o3tl::starts_with(""sv, ""sv)); + CPPUNIT_ASSERT(!o3tl::starts_with(""sv, "foo"sv)); + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, ""sv)); + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, "foo"sv)); + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, "food"sv)); + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, "foobars"sv)); + CPPUNIT_ASSERT(!o3tl::starts_with(""sv, 'f')); + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, 'f')); + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, 'g')); + CPPUNIT_ASSERT(o3tl::starts_with(""sv, "")); + CPPUNIT_ASSERT(!o3tl::starts_with(""sv, "foo")); + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, "")); + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, "foo")); + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, "food")); + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, "foobars")); + CPPUNIT_ASSERT(o3tl::starts_with(""sv, ostringEmpty())); + CPPUNIT_ASSERT(!o3tl::starts_with(""sv, ostringFoo())); + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, ostringEmpty())); + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, ostringFoo())); + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, ostringFood())); + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, ostringFoobars())); + CPPUNIT_ASSERT(o3tl::starts_with(u""sv, u""sv)); + CPPUNIT_ASSERT(!o3tl::starts_with(u""sv, u"foo"sv)); + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, u""sv)); + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, u"foo"sv)); + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, u"food"sv)); + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, u"foobars"sv)); + CPPUNIT_ASSERT(!o3tl::starts_with(u""sv, u'f')); + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, u'f')); + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, u'g')); + CPPUNIT_ASSERT(o3tl::starts_with(u""sv, u"")); + CPPUNIT_ASSERT(!o3tl::starts_with(u""sv, u"foo")); + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, u"")); + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, u"foo")); + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, u"food")); + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, u"foobars")); + CPPUNIT_ASSERT(o3tl::starts_with(u""sv, oustringEmpty())); + CPPUNIT_ASSERT(!o3tl::starts_with(u""sv, oustringFoo())); + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, oustringEmpty())); + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, oustringFoo())); + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, oustringFood())); + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, oustringFoobars())); + } + + void testStartsWithRest() + { + using namespace std::string_view_literals; + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(""sv, ""sv, &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(""sv, "foo"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, ""sv, &rest)); + CPPUNIT_ASSERT_EQUAL("foobar"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, "foo"sv, &rest)); + CPPUNIT_ASSERT_EQUAL("bar"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, "food"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, "foobars"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(""sv, 'f', &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, 'f', &rest)); + CPPUNIT_ASSERT_EQUAL("oobar"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, 'g', &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(""sv, "", &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(""sv, "foo", &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, "", &rest)); + CPPUNIT_ASSERT_EQUAL("foobar"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, "foo", &rest)); + CPPUNIT_ASSERT_EQUAL("bar"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, "food", &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, "foobars", &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(""sv, ostringEmpty(), &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(""sv, ostringFoo(), &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, ostringEmpty(), &rest)); + CPPUNIT_ASSERT_EQUAL("foobar"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with("foobar"sv, ostringFoo(), &rest)); + CPPUNIT_ASSERT_EQUAL("bar"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, ostringFood(), &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with("foobar"sv, ostringFoobars(), &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(u""sv, u""sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u""sv, u"foo"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, u""sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u"foobar"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, u"foo"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u"bar"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, u"food"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, u"foobars"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u""sv, u'f', &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, u'f', &rest)); + CPPUNIT_ASSERT_EQUAL(u"oobar"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, u'g', &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(u""sv, u"", &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u""sv, u"foo", &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, u"", &rest)); + CPPUNIT_ASSERT_EQUAL(u"foobar"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, u"foo", &rest)); + CPPUNIT_ASSERT_EQUAL(u"bar"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, u"food", &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, u"foobars", &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(u""sv, oustringEmpty(), &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u""sv, oustringFoo(), &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, oustringEmpty(), &rest)); + CPPUNIT_ASSERT_EQUAL(u"foobar"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::starts_with(u"foobar"sv, oustringFoo(), &rest)); + CPPUNIT_ASSERT_EQUAL(u"bar"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, oustringFood(), &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::starts_with(u"foobar"sv, oustringFoobars(), &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + } + + void testEndsWith() + { + using namespace std::string_view_literals; + CPPUNIT_ASSERT(o3tl::ends_with(""sv, ""sv)); + CPPUNIT_ASSERT(!o3tl::ends_with(""sv, "oof"sv)); + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, ""sv)); + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, "oof"sv)); + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, "doof"sv)); + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, "sraboof"sv)); + CPPUNIT_ASSERT(!o3tl::ends_with(""sv, 'f')); + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, 'f')); + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, 'g')); + CPPUNIT_ASSERT(o3tl::ends_with(""sv, "")); + CPPUNIT_ASSERT(!o3tl::ends_with(""sv, "oof")); + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, "")); + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, "oof")); + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, "doof")); + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, "sraboof")); + CPPUNIT_ASSERT(o3tl::ends_with(""sv, ostringEmpty())); + CPPUNIT_ASSERT(!o3tl::ends_with(""sv, ostringOof())); + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, ostringEmpty())); + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, ostringOof())); + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, ostringDoof())); + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, ostringSraboof())); + CPPUNIT_ASSERT(o3tl::ends_with(u""sv, u""sv)); + CPPUNIT_ASSERT(!o3tl::ends_with(u""sv, u"oof"sv)); + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, u""sv)); + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, u"oof"sv)); + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, u"doof"sv)); + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, u"sraboof"sv)); + CPPUNIT_ASSERT(!o3tl::ends_with(u""sv, u'f')); + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, u'f')); + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, u'g')); + CPPUNIT_ASSERT(o3tl::ends_with(u""sv, u"")); + CPPUNIT_ASSERT(!o3tl::ends_with(u""sv, u"oof")); + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, u"")); + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, u"oof")); + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, u"doof")); + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, u"sraboof")); + CPPUNIT_ASSERT(o3tl::ends_with(u""sv, oustringEmpty())); + CPPUNIT_ASSERT(!o3tl::ends_with(u""sv, oustringOof())); + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, oustringEmpty())); + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, oustringOof())); + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, oustringDoof())); + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, oustringSraboof())); + } + + void testEndsWithRest() + { + using namespace std::string_view_literals; + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(""sv, ""sv, &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(""sv, "oof"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, ""sv, &rest)); + CPPUNIT_ASSERT_EQUAL("raboof"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, "oof"sv, &rest)); + CPPUNIT_ASSERT_EQUAL("rab"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, "doof"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, "sraboof"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(""sv, 'f', &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, 'f', &rest)); + CPPUNIT_ASSERT_EQUAL("raboo"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, 'g', &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(""sv, "", &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(""sv, "oof", &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, "", &rest)); + CPPUNIT_ASSERT_EQUAL("raboof"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, "oof", &rest)); + CPPUNIT_ASSERT_EQUAL("rab"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, "doof", &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, "sraboof", &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(""sv, ostringEmpty(), &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(""sv, ostringOof(), &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, ostringEmpty(), &rest)); + CPPUNIT_ASSERT_EQUAL("raboof"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with("raboof"sv, ostringOof(), &rest)); + CPPUNIT_ASSERT_EQUAL("rab"sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, ostringDoof(), &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with("raboof"sv, ostringSraboof(), &rest)); + CPPUNIT_ASSERT_EQUAL(""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(u""sv, u""sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u""sv, u"oof"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, u""sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u"raboof"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, u"oof"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u"rab"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, u"doof"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, u"sraboof"sv, &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u""sv, u'f', &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, u'f', &rest)); + CPPUNIT_ASSERT_EQUAL(u"raboo"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, u'g', &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(u""sv, u"", &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u""sv, u"oof", &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, u"", &rest)); + CPPUNIT_ASSERT_EQUAL(u"raboof"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, u"oof", &rest)); + CPPUNIT_ASSERT_EQUAL(u"rab"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, u"doof", &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, u"sraboof", &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(u""sv, oustringEmpty(), &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u""sv, oustringOof(), &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, oustringEmpty(), &rest)); + CPPUNIT_ASSERT_EQUAL(u"raboof"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(o3tl::ends_with(u"raboof"sv, oustringOof(), &rest)); + CPPUNIT_ASSERT_EQUAL(u"rab"sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, oustringDoof(), &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + { + std::u16string_view rest; + CPPUNIT_ASSERT(!o3tl::ends_with(u"raboof"sv, oustringSraboof(), &rest)); + CPPUNIT_ASSERT_EQUAL(u""sv, rest); + } + } + + void testEqualsIgnoreAsciiCase() + { + using namespace std::string_view_literals; + CPPUNIT_ASSERT(o3tl::equalsIgnoreAsciiCase(u"test"sv, u"test"sv)); + CPPUNIT_ASSERT(!o3tl::equalsIgnoreAsciiCase(u"test"sv, u"test2"sv)); + + CPPUNIT_ASSERT_EQUAL(0, o3tl::compareToIgnoreAsciiCase(u"test"sv, u"test"sv)); + CPPUNIT_ASSERT_GREATER(0, o3tl::compareToIgnoreAsciiCase(u"zest"sv, u"test"sv)); + CPPUNIT_ASSERT_LESS(0, o3tl::compareToIgnoreAsciiCase(u"test"sv, u"test2"sv)); + } + + void testGetToken() + { + { + // Explicit initialization of suTokenStr to avoid an unhelpful loplugin:stringviewvar; + // it is the o3tl::getToken overload taking OUString that we want to test here: + OUString suTokenStr(""); + sal_Int32 nIndex = 0; + do + { + o3tl::getToken(suTokenStr, 0, ';', nIndex); + } while (nIndex >= 0); + // should not GPF + } + { + OUString suTokenStr("a;b"); + + sal_Int32 nIndex = 0; + + std::u16string_view suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'a'", std::u16string_view(u"a"), + suToken); + + suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'b'", std::u16string_view(u"b"), + suToken); + CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), + nIndex); + } + { + std::u16string_view suTokenStr(u"a;b.c"); + + sal_Int32 nIndex = 0; + + std::u16string_view suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'a'", std::u16string_view(u"a"), + suToken); + + suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'b'", std::u16string_view(u"b"), + suToken); + + suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'c'", std::u16string_view(u"c"), + suToken); + CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), + nIndex); + } + { + std::u16string_view suTokenStr(u"a;;b"); + + sal_Int32 nIndex = 0; + + std::u16string_view suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'a'", std::u16string_view(u"a"), + suToken); + + suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex); + CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.empty()); + + suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'b'", std::u16string_view(u"b"), + suToken); + CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), + nIndex); + } + { + std::u16string_view suTokenStr(u"longer.then.ever."); + + sal_Int32 nIndex = 0; + + std::u16string_view suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be 'longer'", std::u16string_view(u"longer"), + suToken); + + suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be 'then'", std::u16string_view(u"then"), + suToken); + + suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be 'ever'", std::u16string_view(u"ever"), + suToken); + + suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex); + CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.empty()); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), + nIndex); + } + { + std::u16string_view ab(u"ab"); + sal_Int32 n = 0; + CPPUNIT_ASSERT_EQUAL_MESSAGE("token should be 'ab'", ab, o3tl::getToken(ab, 0, '-', n)); + CPPUNIT_ASSERT_EQUAL_MESSAGE("n should be -1", static_cast<sal_Int32>(-1), n); + CPPUNIT_ASSERT_MESSAGE("token should be empty", o3tl::getToken(ab, 0, '-', n).empty()); + } + { + std::u16string_view suTokenStr; + auto pTokenStr = suTokenStr.data(); + sal_uInt64 n64 = reinterpret_cast<sal_uInt64>(pTokenStr) / sizeof(sal_Unicode); + // Point either to 0x0, or to some random address -4GiB away from this string + sal_Int32 n = n64 > o3tl::make_unsigned(SAL_MAX_INT32) ? -SAL_MAX_INT32 + : -static_cast<sal_Int32>(n64); + o3tl::getToken(suTokenStr, 0, ';', n); + // should not GPF with negative index + } + { + CPPUNIT_ASSERT_MESSAGE("compareToAscii", + u"aaa"_ustr.compareToAscii("aa") + > 0); // just for comparison to following line + CPPUNIT_ASSERT_MESSAGE("compareToAscii", o3tl::compareToAscii(u"aaa", "aa") > 0); + + OUString aa(u"aa"_ustr); + CPPUNIT_ASSERT_MESSAGE("compareToAscii", + aa.compareToAscii("aaa") + < 0); // just for comparison to following line + CPPUNIT_ASSERT_MESSAGE("compareToAscii", o3tl::compareToAscii(u"aa", "aaa") < 0); + + CPPUNIT_ASSERT_MESSAGE( + "equalsIgnoreAsciiCase", + aa.equalsIgnoreAsciiCase("AA")); // just for comparison to following line + CPPUNIT_ASSERT_MESSAGE("equalsIgnoreAsciiCase", + o3tl::equalsIgnoreAsciiCase(u"aa", "AA")); + + CPPUNIT_ASSERT_MESSAGE( + "matchIgnoreAsciiCase", + aa.matchIgnoreAsciiCase("a")); // just for comparison to following line + CPPUNIT_ASSERT_MESSAGE("matchIgnoreAsciiCase", o3tl::matchIgnoreAsciiCase(u"aa", "a")); + + CPPUNIT_ASSERT_MESSAGE( + "endsWithIgnoreAsciiCase", + aa.endsWithIgnoreAsciiCase("a")); // just for comparison to following line + CPPUNIT_ASSERT_MESSAGE("endsWithIgnoreAsciiCase", + o3tl::endsWithIgnoreAsciiCase(u"aa", "a")); + CPPUNIT_ASSERT_MESSAGE("endsWithIgnoreAsciiCase", + o3tl::endsWithIgnoreAsciiCase(u"aa", u"a")); + } + } + + void testIterateCodePoints() + { + { + sal_Int32 i = 1; + auto const c = o3tl::iterateCodePoints(u"\U00010000", &i, 1); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDC00), c); + } + { + sal_Int32 i = 2; + auto const c = o3tl::iterateCodePoints(u"a\U00010000", &i, -1); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), c); + } + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/o3tl/qa/test-temporary.cxx b/o3tl/qa/test-temporary.cxx new file mode 100644 index 0000000000..6f775de847 --- /dev/null +++ b/o3tl/qa/test-temporary.cxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <o3tl/temporary.hxx> + +namespace +{ +void modify(int& n) { n = 1; } + +class Test : public CppUnit::TestFixture +{ +private: + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testLvalue); + CPPUNIT_TEST_SUITE_END(); + + void testLvalue() + { + { + int n = 0; + modify(n); + CPPUNIT_ASSERT_EQUAL(1, n); + } + { + int n = 0; + modify(o3tl::temporary(int(n))); + CPPUNIT_ASSERT_EQUAL(0, n); + } + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/o3tl/qa/test-typed_flags.cxx b/o3tl/qa/test-typed_flags.cxx new file mode 100644 index 0000000000..ef6e4faaed --- /dev/null +++ b/o3tl/qa/test-typed_flags.cxx @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <o3tl/typed_flags_set.hxx> + +using namespace ::o3tl; + +namespace { + +enum class ConfigurationChangedHint { NONE, ONE, TWO }; + +} + +namespace o3tl +{ + template<> struct typed_flags< ConfigurationChangedHint> : is_typed_flags< ConfigurationChangedHint, 0xFF> {}; +} + +class typed_flags_test : public CppUnit::TestFixture +{ +public: + void testBasics() + { + ConfigurationChangedHint nHint = ConfigurationChangedHint::ONE; + + CPPUNIT_ASSERT( ConfigurationChangedHint::ONE & ConfigurationChangedHint::ONE ); + CPPUNIT_ASSERT( nHint & ConfigurationChangedHint::ONE ); + CPPUNIT_ASSERT( ConfigurationChangedHint::ONE & nHint ); + + CPPUNIT_ASSERT( ConfigurationChangedHint::ONE | ConfigurationChangedHint::ONE ); + CPPUNIT_ASSERT( nHint | ConfigurationChangedHint::ONE ); + CPPUNIT_ASSERT( ConfigurationChangedHint::ONE | nHint ); + + CPPUNIT_ASSERT( ~nHint ); + CPPUNIT_ASSERT( ~ConfigurationChangedHint::ONE ); + + nHint |= ConfigurationChangedHint::ONE; + CPPUNIT_ASSERT( bool(nHint |= ConfigurationChangedHint::ONE) ); + + nHint &= ConfigurationChangedHint::ONE; + CPPUNIT_ASSERT( bool(nHint &= ConfigurationChangedHint::ONE) ); + + CPPUNIT_ASSERT( + !((ConfigurationChangedHint::NONE | ConfigurationChangedHint::ONE) + & (ConfigurationChangedHint::NONE + | ConfigurationChangedHint::TWO))); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(typed_flags_test); + CPPUNIT_TEST(testBasics); + CPPUNIT_TEST_SUITE_END(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(typed_flags_test); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/o3tl/qa/test-unit_conversion.cxx b/o3tl/qa/test-unit_conversion.cxx new file mode 100644 index 0000000000..d140f1da7e --- /dev/null +++ b/o3tl/qa/test-unit_conversion.cxx @@ -0,0 +1,883 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> + +#include <o3tl/unit_conversion.hxx> + +// Just some static asserts + +namespace +{ +constexpr double const_abs(double f) { return f >= 0 ? f : -f; } +constexpr bool eq(double a, double b) { return const_abs(a - b) < 1E-6; } +bool eq(sal_Int64, double) = delete; +} + +// testing floating-point conversion + +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mm100, o3tl::Length::mm100), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mm10, o3tl::Length::mm100), 10)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mm, o3tl::Length::mm100), 100)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::cm, o3tl::Length::mm100), 1000)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::m, o3tl::Length::mm100), 100000)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::km, o3tl::Length::mm100), 100E6)); +static_assert(eq(o3tl::convert(360.0, o3tl::Length::emu, o3tl::Length::mm100), 1)); +static_assert(eq(o3tl::convert(72.0, o3tl::Length::twip, o3tl::Length::mm100), 127)); +static_assert(eq(o3tl::convert(18.0, o3tl::Length::pt, o3tl::Length::mm100), 635)); +static_assert(eq(o3tl::convert(3.0, o3tl::Length::pc, o3tl::Length::mm100), 1270)); +static_assert(eq(o3tl::convert(50.0, o3tl::Length::in1000, o3tl::Length::mm100), 127)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::in100, o3tl::Length::mm100), 127)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in10, o3tl::Length::mm100), 254)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::mm100), 2540)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::mm100), 30480)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::mm100), 160934400)); +static_assert(eq(o3tl::convert(144.0, o3tl::Length::master, o3tl::Length::mm100), 635)); +static_assert(eq(o3tl::convert(24.0, o3tl::Length::px, o3tl::Length::mm100), 635)); +static_assert(eq(o3tl::convert(12.0, o3tl::Length::ch, o3tl::Length::mm100), 4445)); +static_assert(eq(o3tl::convert(3.0, o3tl::Length::line, o3tl::Length::mm100), 1651)); + +static_assert(eq(o3tl::convert(10.0, o3tl::Length::mm100, o3tl::Length::mm10), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mm10, o3tl::Length::mm10), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mm, o3tl::Length::mm10), 10)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::cm, o3tl::Length::mm10), 100)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::m, o3tl::Length::mm10), 10000)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::km, o3tl::Length::mm10), 10E6)); +static_assert(eq(o3tl::convert(3600.0, o3tl::Length::emu, o3tl::Length::mm10), 1)); +static_assert(eq(o3tl::convert(720.0, o3tl::Length::twip, o3tl::Length::mm10), 127)); +static_assert(eq(o3tl::convert(36.0, o3tl::Length::pt, o3tl::Length::mm10), 127)); +static_assert(eq(o3tl::convert(3.0, o3tl::Length::pc, o3tl::Length::mm10), 127)); +static_assert(eq(o3tl::convert(500.0, o3tl::Length::in1000, o3tl::Length::mm10), 127)); +static_assert(eq(o3tl::convert(50.0, o3tl::Length::in100, o3tl::Length::mm10), 127)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::in10, o3tl::Length::mm10), 127)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::mm10), 254)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::mm10), 3048)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::mm10), 16093440)); +static_assert(eq(o3tl::convert(288.0, o3tl::Length::master, o3tl::Length::mm10), 127)); +static_assert(eq(o3tl::convert(48.0, o3tl::Length::px, o3tl::Length::mm10), 127)); +static_assert(eq(o3tl::convert(24.0, o3tl::Length::ch, o3tl::Length::mm10), 889)); +static_assert(eq(o3tl::convert(30.0, o3tl::Length::line, o3tl::Length::mm10), 1651)); + +static_assert(eq(o3tl::convert(100.0, o3tl::Length::mm100, o3tl::Length::mm), 1)); +static_assert(eq(o3tl::convert(10.0, o3tl::Length::mm10, o3tl::Length::mm), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mm, o3tl::Length::mm), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::cm, o3tl::Length::mm), 10)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::m, o3tl::Length::mm), 1000)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::km, o3tl::Length::mm), 1E6)); +static_assert(eq(o3tl::convert(36000.0, o3tl::Length::emu, o3tl::Length::mm), 1)); +static_assert(eq(o3tl::convert(7200.0, o3tl::Length::twip, o3tl::Length::mm), 127)); +static_assert(eq(o3tl::convert(360.0, o3tl::Length::pt, o3tl::Length::mm), 127)); +static_assert(eq(o3tl::convert(30.0, o3tl::Length::pc, o3tl::Length::mm), 127)); +static_assert(eq(o3tl::convert(5000.0, o3tl::Length::in1000, o3tl::Length::mm), 127)); +static_assert(eq(o3tl::convert(500.0, o3tl::Length::in100, o3tl::Length::mm), 127)); +static_assert(eq(o3tl::convert(50.0, o3tl::Length::in10, o3tl::Length::mm), 127)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::in, o3tl::Length::mm), 127)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::ft, o3tl::Length::mm), 1524)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::mm), 1609344)); +static_assert(eq(o3tl::convert(2880.0, o3tl::Length::master, o3tl::Length::mm), 127)); +static_assert(eq(o3tl::convert(480.0, o3tl::Length::px, o3tl::Length::mm), 127)); +static_assert(eq(o3tl::convert(240.0, o3tl::Length::ch, o3tl::Length::mm), 889)); +static_assert(eq(o3tl::convert(300.0, o3tl::Length::line, o3tl::Length::mm), 1651)); + +static_assert(eq(o3tl::convert(1000.0, o3tl::Length::mm100, o3tl::Length::cm), 1)); +static_assert(eq(o3tl::convert(100.0, o3tl::Length::mm10, o3tl::Length::cm), 1)); +static_assert(eq(o3tl::convert(10.0, o3tl::Length::mm, o3tl::Length::cm), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::cm, o3tl::Length::cm), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::m, o3tl::Length::cm), 100)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::km, o3tl::Length::cm), 100000)); +static_assert(eq(o3tl::convert(360000.0, o3tl::Length::emu, o3tl::Length::cm), 1)); +static_assert(eq(o3tl::convert(72000.0, o3tl::Length::twip, o3tl::Length::cm), 127)); +static_assert(eq(o3tl::convert(3600.0, o3tl::Length::pt, o3tl::Length::cm), 127)); +static_assert(eq(o3tl::convert(300.0, o3tl::Length::pc, o3tl::Length::cm), 127)); +static_assert(eq(o3tl::convert(50000.0, o3tl::Length::in1000, o3tl::Length::cm), 127)); +static_assert(eq(o3tl::convert(5000.0, o3tl::Length::in100, o3tl::Length::cm), 127)); +static_assert(eq(o3tl::convert(500.0, o3tl::Length::in10, o3tl::Length::cm), 127)); +static_assert(eq(o3tl::convert(50.0, o3tl::Length::in, o3tl::Length::cm), 127)); +static_assert(eq(o3tl::convert(25.0, o3tl::Length::ft, o3tl::Length::cm), 762)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::mi, o3tl::Length::cm), 804672)); +static_assert(eq(o3tl::convert(28800.0, o3tl::Length::master, o3tl::Length::cm), 127)); +static_assert(eq(o3tl::convert(4800.0, o3tl::Length::px, o3tl::Length::cm), 127)); +static_assert(eq(o3tl::convert(2400.0, o3tl::Length::ch, o3tl::Length::cm), 889)); +static_assert(eq(o3tl::convert(3000.0, o3tl::Length::line, o3tl::Length::cm), 1651)); + +static_assert(eq(o3tl::convert(100000.0, o3tl::Length::mm100, o3tl::Length::m), 1)); +static_assert(eq(o3tl::convert(10000.0, o3tl::Length::mm10, o3tl::Length::m), 1)); +static_assert(eq(o3tl::convert(1000.0, o3tl::Length::mm, o3tl::Length::m), 1)); +static_assert(eq(o3tl::convert(100.0, o3tl::Length::cm, o3tl::Length::m), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::m, o3tl::Length::m), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::km, o3tl::Length::m), 1000)); +static_assert(eq(o3tl::convert(36E6, o3tl::Length::emu, o3tl::Length::m), 1)); +static_assert(eq(o3tl::convert(7200000.0, o3tl::Length::twip, o3tl::Length::m), 127)); +static_assert(eq(o3tl::convert(360000.0, o3tl::Length::pt, o3tl::Length::m), 127)); +static_assert(eq(o3tl::convert(30000.0, o3tl::Length::pc, o3tl::Length::m), 127)); +static_assert(eq(o3tl::convert(5000000.0, o3tl::Length::in1000, o3tl::Length::m), 127)); +static_assert(eq(o3tl::convert(500000.0, o3tl::Length::in100, o3tl::Length::m), 127)); +static_assert(eq(o3tl::convert(50000.0, o3tl::Length::in10, o3tl::Length::m), 127)); +static_assert(eq(o3tl::convert(5000.0, o3tl::Length::in, o3tl::Length::m), 127)); +static_assert(eq(o3tl::convert(1250.0, o3tl::Length::ft, o3tl::Length::m), 381)); +static_assert(eq(o3tl::convert(125.0, o3tl::Length::mi, o3tl::Length::m), 201168)); +static_assert(eq(o3tl::convert(2880000.0, o3tl::Length::master, o3tl::Length::m), 127)); +static_assert(eq(o3tl::convert(480000.0, o3tl::Length::px, o3tl::Length::m), 127)); +static_assert(eq(o3tl::convert(240000.0, o3tl::Length::ch, o3tl::Length::m), 889)); +static_assert(eq(o3tl::convert(300000.0, o3tl::Length::line, o3tl::Length::m), 1651)); + +static_assert(eq(o3tl::convert(100E6, o3tl::Length::mm100, o3tl::Length::km), 1)); +static_assert(eq(o3tl::convert(10E6, o3tl::Length::mm10, o3tl::Length::km), 1)); +static_assert(eq(o3tl::convert(1E6, o3tl::Length::mm, o3tl::Length::km), 1)); +static_assert(eq(o3tl::convert(100000.0, o3tl::Length::cm, o3tl::Length::km), 1)); +static_assert(eq(o3tl::convert(1000.0, o3tl::Length::m, o3tl::Length::km), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::km, o3tl::Length::km), 1)); +static_assert(eq(o3tl::convert(36E9, o3tl::Length::emu, o3tl::Length::km), 1)); +static_assert(eq(o3tl::convert(7200E6, o3tl::Length::twip, o3tl::Length::km), 127)); +static_assert(eq(o3tl::convert(360E6, o3tl::Length::pt, o3tl::Length::km), 127)); +static_assert(eq(o3tl::convert(30E6, o3tl::Length::pc, o3tl::Length::km), 127)); +static_assert(eq(o3tl::convert(5E9, o3tl::Length::in1000, o3tl::Length::km), 127)); +static_assert(eq(o3tl::convert(500E6, o3tl::Length::in100, o3tl::Length::km), 127)); +static_assert(eq(o3tl::convert(50E6, o3tl::Length::in10, o3tl::Length::km), 127)); +static_assert(eq(o3tl::convert(5E6, o3tl::Length::in, o3tl::Length::km), 127)); +static_assert(eq(o3tl::convert(1250000.0, o3tl::Length::ft, o3tl::Length::km), 381)); +static_assert(eq(o3tl::convert(15625.0, o3tl::Length::mi, o3tl::Length::km), 25146)); +static_assert(eq(o3tl::convert(2880E6, o3tl::Length::master, o3tl::Length::km), 127)); +static_assert(eq(o3tl::convert(480E6, o3tl::Length::px, o3tl::Length::km), 127)); +static_assert(eq(o3tl::convert(240E6, o3tl::Length::ch, o3tl::Length::km), 889)); +static_assert(eq(o3tl::convert(300E6, o3tl::Length::line, o3tl::Length::km), 1651)); + +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mm100, o3tl::Length::emu), 360)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mm10, o3tl::Length::emu), 3600)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mm, o3tl::Length::emu), 36000)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::cm, o3tl::Length::emu), 360000)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::m, o3tl::Length::emu), 36E6)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::km, o3tl::Length::emu), 36E9)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::emu, o3tl::Length::emu), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::twip, o3tl::Length::emu), 635)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::pt, o3tl::Length::emu), 12700)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::pc, o3tl::Length::emu), 152400)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::in1000, o3tl::Length::emu), 4572)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in100, o3tl::Length::emu), 9144)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in10, o3tl::Length::emu), 91440)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::emu), 914400)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::emu), 10972800)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::emu), 57936384000)); +static_assert(eq(o3tl::convert(2.0, o3tl::Length::master, o3tl::Length::emu), 3175)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::px, o3tl::Length::emu), 9525)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ch, o3tl::Length::emu), 133350)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::line, o3tl::Length::emu), 198120)); + +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm100, o3tl::Length::twip), 72)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm10, o3tl::Length::twip), 720)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm, o3tl::Length::twip), 7200)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::cm, o3tl::Length::twip), 72000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::m, o3tl::Length::twip), 7200000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::km, o3tl::Length::twip), 7200E6)); +static_assert(eq(o3tl::convert(635.0, o3tl::Length::emu, o3tl::Length::twip), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::twip, o3tl::Length::twip), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::pt, o3tl::Length::twip), 20)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::pc, o3tl::Length::twip), 240)); +static_assert(eq(o3tl::convert(25.0, o3tl::Length::in1000, o3tl::Length::twip), 36)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::in100, o3tl::Length::twip), 72)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in10, o3tl::Length::twip), 144)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::twip), 1440)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::twip), 17280)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::twip), 91238400)); +static_assert(eq(o3tl::convert(2.0, o3tl::Length::master, o3tl::Length::twip), 5)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::px, o3tl::Length::twip), 15)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ch, o3tl::Length::twip), 210)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::line, o3tl::Length::twip), 312)); + +static_assert(eq(o3tl::convert(635.0, o3tl::Length::mm100, o3tl::Length::pt), 18)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm10, o3tl::Length::pt), 36)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm, o3tl::Length::pt), 360)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::cm, o3tl::Length::pt), 3600)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::m, o3tl::Length::pt), 360000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::km, o3tl::Length::pt), 360E6)); +static_assert(eq(o3tl::convert(12700.0, o3tl::Length::emu, o3tl::Length::pt), 1)); +static_assert(eq(o3tl::convert(20.0, o3tl::Length::twip, o3tl::Length::pt), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::pt, o3tl::Length::pt), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::pc, o3tl::Length::pt), 12)); +static_assert(eq(o3tl::convert(125.0, o3tl::Length::in1000, o3tl::Length::pt), 9)); +static_assert(eq(o3tl::convert(25.0, o3tl::Length::in100, o3tl::Length::pt), 18)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::in10, o3tl::Length::pt), 36)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::pt), 72)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::pt), 864)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::pt), 4561920)); +static_assert(eq(o3tl::convert(8.0, o3tl::Length::master, o3tl::Length::pt), 1)); +static_assert(eq(o3tl::convert(4.0, o3tl::Length::px, o3tl::Length::pt), 3)); +static_assert(eq(o3tl::convert(2.0, o3tl::Length::ch, o3tl::Length::pt), 21)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::line, o3tl::Length::pt), 78)); + +static_assert(eq(o3tl::convert(1270.0, o3tl::Length::mm100, o3tl::Length::pc), 3)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm10, o3tl::Length::pc), 3)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm, o3tl::Length::pc), 30)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::cm, o3tl::Length::pc), 300)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::m, o3tl::Length::pc), 30000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::km, o3tl::Length::pc), 30E6)); +static_assert(eq(o3tl::convert(152400.0, o3tl::Length::emu, o3tl::Length::pc), 1)); +static_assert(eq(o3tl::convert(240.0, o3tl::Length::twip, o3tl::Length::pc), 1)); +static_assert(eq(o3tl::convert(12.0, o3tl::Length::pt, o3tl::Length::pc), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::pc, o3tl::Length::pc), 1)); +static_assert(eq(o3tl::convert(500.0, o3tl::Length::in1000, o3tl::Length::pc), 3)); +static_assert(eq(o3tl::convert(50.0, o3tl::Length::in100, o3tl::Length::pc), 3)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::in10, o3tl::Length::pc), 3)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::pc), 6)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::pc), 72)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::pc), 380160)); +static_assert(eq(o3tl::convert(96.0, o3tl::Length::master, o3tl::Length::pc), 1)); +static_assert(eq(o3tl::convert(16.0, o3tl::Length::px, o3tl::Length::pc), 1)); +static_assert(eq(o3tl::convert(8.0, o3tl::Length::ch, o3tl::Length::pc), 7)); +static_assert(eq(o3tl::convert(10.0, o3tl::Length::line, o3tl::Length::pc), 13)); + +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm100, o3tl::Length::in1000), 50)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm10, o3tl::Length::in1000), 500)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm, o3tl::Length::in1000), 5000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::cm, o3tl::Length::in1000), 50000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::m, o3tl::Length::in1000), 5E6)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::km, o3tl::Length::in1000), 5E9)); +static_assert(eq(o3tl::convert(4572.0, o3tl::Length::emu, o3tl::Length::in1000), 5)); +static_assert(eq(o3tl::convert(36.0, o3tl::Length::twip, o3tl::Length::in1000), 25)); +static_assert(eq(o3tl::convert(9.0, o3tl::Length::pt, o3tl::Length::in1000), 125)); +static_assert(eq(o3tl::convert(3.0, o3tl::Length::pc, o3tl::Length::in1000), 500)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in1000, o3tl::Length::in1000), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in100, o3tl::Length::in1000), 10)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in10, o3tl::Length::in1000), 100)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::in1000), 1000)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::in1000), 12000)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::in1000), 63360000)); +static_assert(eq(o3tl::convert(72.0, o3tl::Length::master, o3tl::Length::in1000), 125)); +static_assert(eq(o3tl::convert(12.0, o3tl::Length::px, o3tl::Length::in1000), 125)); +static_assert(eq(o3tl::convert(6.0, o3tl::Length::ch, o3tl::Length::in1000), 875)); +static_assert(eq(o3tl::convert(3.0, o3tl::Length::line, o3tl::Length::in1000), 650)); + +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm100, o3tl::Length::in100), 5)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm10, o3tl::Length::in100), 50)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm, o3tl::Length::in100), 500)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::cm, o3tl::Length::in100), 5000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::m, o3tl::Length::in100), 500000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::km, o3tl::Length::in100), 500E6)); +static_assert(eq(o3tl::convert(9144.0, o3tl::Length::emu, o3tl::Length::in100), 1)); +static_assert(eq(o3tl::convert(72.0, o3tl::Length::twip, o3tl::Length::in100), 5)); +static_assert(eq(o3tl::convert(18.0, o3tl::Length::pt, o3tl::Length::in100), 25)); +static_assert(eq(o3tl::convert(3.0, o3tl::Length::pc, o3tl::Length::in100), 50)); +static_assert(eq(o3tl::convert(10.0, o3tl::Length::in1000, o3tl::Length::in100), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in100, o3tl::Length::in100), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in10, o3tl::Length::in100), 10)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::in100), 100)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::in100), 1200)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::in100), 6336000)); +static_assert(eq(o3tl::convert(144.0, o3tl::Length::master, o3tl::Length::in100), 25)); +static_assert(eq(o3tl::convert(24.0, o3tl::Length::px, o3tl::Length::in100), 25)); +static_assert(eq(o3tl::convert(12.0, o3tl::Length::ch, o3tl::Length::in100), 175)); +static_assert(eq(o3tl::convert(3.0, o3tl::Length::line, o3tl::Length::in100), 65)); + +static_assert(eq(o3tl::convert(254.0, o3tl::Length::mm100, o3tl::Length::in10), 1)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm10, o3tl::Length::in10), 5)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm, o3tl::Length::in10), 50)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::cm, o3tl::Length::in10), 500)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::m, o3tl::Length::in10), 50000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::km, o3tl::Length::in10), 50E6)); +static_assert(eq(o3tl::convert(91440.0, o3tl::Length::emu, o3tl::Length::in10), 1)); +static_assert(eq(o3tl::convert(144.0, o3tl::Length::twip, o3tl::Length::in10), 1)); +static_assert(eq(o3tl::convert(36.0, o3tl::Length::pt, o3tl::Length::in10), 5)); +static_assert(eq(o3tl::convert(3.0, o3tl::Length::pc, o3tl::Length::in10), 5)); +static_assert(eq(o3tl::convert(100.0, o3tl::Length::in1000, o3tl::Length::in10), 1)); +static_assert(eq(o3tl::convert(10.0, o3tl::Length::in100, o3tl::Length::in10), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in10, o3tl::Length::in10), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::in10), 10)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::in10), 120)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::in10), 633600)); +static_assert(eq(o3tl::convert(288.0, o3tl::Length::master, o3tl::Length::in10), 5)); +static_assert(eq(o3tl::convert(48.0, o3tl::Length::px, o3tl::Length::in10), 5)); +static_assert(eq(o3tl::convert(24.0, o3tl::Length::ch, o3tl::Length::in10), 35)); +static_assert(eq(o3tl::convert(6.0, o3tl::Length::line, o3tl::Length::in10), 13)); + +static_assert(eq(o3tl::convert(2540.0, o3tl::Length::mm100, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(254.0, o3tl::Length::mm10, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm, o3tl::Length::in), 5)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::cm, o3tl::Length::in), 50)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::m, o3tl::Length::in), 5000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::km, o3tl::Length::in), 5E6)); +static_assert(eq(o3tl::convert(914400.0, o3tl::Length::emu, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(1440.0, o3tl::Length::twip, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(72.0, o3tl::Length::pt, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(6.0, o3tl::Length::pc, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(1000.0, o3tl::Length::in1000, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(100.0, o3tl::Length::in100, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(10.0, o3tl::Length::in10, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::in), 12)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::in), 63360)); +static_assert(eq(o3tl::convert(576.0, o3tl::Length::master, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(96.0, o3tl::Length::px, o3tl::Length::in), 1)); +static_assert(eq(o3tl::convert(48.0, o3tl::Length::ch, o3tl::Length::in), 7)); +static_assert(eq(o3tl::convert(60.0, o3tl::Length::line, o3tl::Length::in), 13)); + +static_assert(eq(o3tl::convert(30480.0, o3tl::Length::mm100, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(3048.0, o3tl::Length::mm10, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(1524.0, o3tl::Length::mm, o3tl::Length::ft), 5)); +static_assert(eq(o3tl::convert(762.0, o3tl::Length::cm, o3tl::Length::ft), 25)); +static_assert(eq(o3tl::convert(381.0, o3tl::Length::m, o3tl::Length::ft), 1250)); +static_assert(eq(o3tl::convert(381.0, o3tl::Length::km, o3tl::Length::ft), 1250000)); +static_assert(eq(o3tl::convert(10972800.0, o3tl::Length::emu, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(17280.0, o3tl::Length::twip, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(864.0, o3tl::Length::pt, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(72.0, o3tl::Length::pc, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(12000.0, o3tl::Length::in1000, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(1200.0, o3tl::Length::in100, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(120.0, o3tl::Length::in10, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(12.0, o3tl::Length::in, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::ft), 5280)); +static_assert(eq(o3tl::convert(6912.0, o3tl::Length::master, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(1152.0, o3tl::Length::px, o3tl::Length::ft), 1)); +static_assert(eq(o3tl::convert(576.0, o3tl::Length::ch, o3tl::Length::ft), 7)); +static_assert(eq(o3tl::convert(720.0, o3tl::Length::line, o3tl::Length::ft), 13)); + +static_assert(eq(o3tl::convert(160934400.0, o3tl::Length::mm100, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(16093440.0, o3tl::Length::mm10, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(1609344.0, o3tl::Length::mm, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(804672.0, o3tl::Length::cm, o3tl::Length::mi), 5)); +static_assert(eq(o3tl::convert(201168.0, o3tl::Length::m, o3tl::Length::mi), 125)); +static_assert(eq(o3tl::convert(25146.0, o3tl::Length::km, o3tl::Length::mi), 15625)); +static_assert(eq(o3tl::convert(57936384000.0, o3tl::Length::emu, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(91238400.0, o3tl::Length::twip, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(4561920.0, o3tl::Length::pt, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(380160.0, o3tl::Length::pc, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(63360000.0, o3tl::Length::in1000, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(6336000.0, o3tl::Length::in100, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(633600.0, o3tl::Length::in10, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(63360.0, o3tl::Length::in, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(5280.0, o3tl::Length::ft, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(36495360.0, o3tl::Length::master, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(6082560.0, o3tl::Length::px, o3tl::Length::mi), 1)); +static_assert(eq(o3tl::convert(3041280.0, o3tl::Length::ch, o3tl::Length::mi), 7)); +static_assert(eq(o3tl::convert(3801600.0, o3tl::Length::line, o3tl::Length::mi), 13)); + +static_assert(eq(o3tl::convert(635.0, o3tl::Length::mm100, o3tl::Length::master), 144)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm10, o3tl::Length::master), 288)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm, o3tl::Length::master), 2880)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::cm, o3tl::Length::master), 28800)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::m, o3tl::Length::master), 2880000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::km, o3tl::Length::master), 2880E6)); +static_assert(eq(o3tl::convert(3175.0, o3tl::Length::emu, o3tl::Length::master), 2)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::twip, o3tl::Length::master), 2)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::pt, o3tl::Length::master), 8)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::pc, o3tl::Length::master), 96)); +static_assert(eq(o3tl::convert(125.0, o3tl::Length::in1000, o3tl::Length::master), 72)); +static_assert(eq(o3tl::convert(25.0, o3tl::Length::in100, o3tl::Length::master), 144)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::in10, o3tl::Length::master), 288)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::master), 576)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::master), 6912)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::master), 36495360)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::master, o3tl::Length::master), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::px, o3tl::Length::master), 6)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ch, o3tl::Length::master), 84)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::line, o3tl::Length::master), 624)); + +static_assert(eq(o3tl::convert(635.0, o3tl::Length::mm100, o3tl::Length::px), 24)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm10, o3tl::Length::px), 48)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::mm, o3tl::Length::px), 480)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::cm, o3tl::Length::px), 4800)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::m, o3tl::Length::px), 480000)); +static_assert(eq(o3tl::convert(127.0, o3tl::Length::km, o3tl::Length::px), 480E6)); +static_assert(eq(o3tl::convert(9525.0, o3tl::Length::emu, o3tl::Length::px), 1)); +static_assert(eq(o3tl::convert(15.0, o3tl::Length::twip, o3tl::Length::px), 1)); +static_assert(eq(o3tl::convert(3.0, o3tl::Length::pt, o3tl::Length::px), 4)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::pc, o3tl::Length::px), 16)); +static_assert(eq(o3tl::convert(125.0, o3tl::Length::in1000, o3tl::Length::px), 12)); +static_assert(eq(o3tl::convert(25.0, o3tl::Length::in100, o3tl::Length::px), 24)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::in10, o3tl::Length::px), 48)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::in, o3tl::Length::px), 96)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ft, o3tl::Length::px), 1152)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::mi, o3tl::Length::px), 6082560)); +static_assert(eq(o3tl::convert(6.0, o3tl::Length::master, o3tl::Length::px), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::px, o3tl::Length::px), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ch, o3tl::Length::px), 14)); +static_assert(eq(o3tl::convert(5.0, o3tl::Length::line, o3tl::Length::px), 104)); + +static_assert(eq(o3tl::convert(4445.0, o3tl::Length::mm100, o3tl::Length::ch), 12)); +static_assert(eq(o3tl::convert(889.0, o3tl::Length::mm10, o3tl::Length::ch), 24)); +static_assert(eq(o3tl::convert(889.0, o3tl::Length::mm, o3tl::Length::ch), 240)); +static_assert(eq(o3tl::convert(889.0, o3tl::Length::cm, o3tl::Length::ch), 2400)); +static_assert(eq(o3tl::convert(889.0, o3tl::Length::m, o3tl::Length::ch), 240000)); +static_assert(eq(o3tl::convert(889.0, o3tl::Length::km, o3tl::Length::ch), 240E6)); +static_assert(eq(o3tl::convert(133350.0, o3tl::Length::emu, o3tl::Length::ch), 1)); +static_assert(eq(o3tl::convert(210.0, o3tl::Length::twip, o3tl::Length::ch), 1)); +static_assert(eq(o3tl::convert(21.0, o3tl::Length::pt, o3tl::Length::ch), 2)); +static_assert(eq(o3tl::convert(7.0, o3tl::Length::pc, o3tl::Length::ch), 8)); +static_assert(eq(o3tl::convert(875.0, o3tl::Length::in1000, o3tl::Length::ch), 6)); +static_assert(eq(o3tl::convert(175.0, o3tl::Length::in100, o3tl::Length::ch), 12)); +static_assert(eq(o3tl::convert(35.0, o3tl::Length::in10, o3tl::Length::ch), 24)); +static_assert(eq(o3tl::convert(7.0, o3tl::Length::in, o3tl::Length::ch), 48)); +static_assert(eq(o3tl::convert(7.0, o3tl::Length::ft, o3tl::Length::ch), 576)); +static_assert(eq(o3tl::convert(7.0, o3tl::Length::mi, o3tl::Length::ch), 3041280)); +static_assert(eq(o3tl::convert(84.0, o3tl::Length::master, o3tl::Length::ch), 1)); +static_assert(eq(o3tl::convert(14.0, o3tl::Length::px, o3tl::Length::ch), 1)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::ch, o3tl::Length::ch), 1)); +static_assert(eq(o3tl::convert(35.0, o3tl::Length::line, o3tl::Length::ch), 52)); + +static_assert(eq(o3tl::convert(1651.0, o3tl::Length::mm100, o3tl::Length::line), 3)); +static_assert(eq(o3tl::convert(1651.0, o3tl::Length::mm10, o3tl::Length::line), 30)); +static_assert(eq(o3tl::convert(1651.0, o3tl::Length::mm, o3tl::Length::line), 300)); +static_assert(eq(o3tl::convert(1651.0, o3tl::Length::cm, o3tl::Length::line), 3000)); +static_assert(eq(o3tl::convert(1651.0, o3tl::Length::m, o3tl::Length::line), 300000)); +static_assert(eq(o3tl::convert(1651.0, o3tl::Length::km, o3tl::Length::line), 300E6)); +static_assert(eq(o3tl::convert(198120.0, o3tl::Length::emu, o3tl::Length::line), 1)); +static_assert(eq(o3tl::convert(312.0, o3tl::Length::twip, o3tl::Length::line), 1)); +static_assert(eq(o3tl::convert(78.0, o3tl::Length::pt, o3tl::Length::line), 5)); +static_assert(eq(o3tl::convert(13.0, o3tl::Length::pc, o3tl::Length::line), 10)); +static_assert(eq(o3tl::convert(650.0, o3tl::Length::in1000, o3tl::Length::line), 3)); +static_assert(eq(o3tl::convert(65.0, o3tl::Length::in100, o3tl::Length::line), 3)); +static_assert(eq(o3tl::convert(13.0, o3tl::Length::in10, o3tl::Length::line), 6)); +static_assert(eq(o3tl::convert(13.0, o3tl::Length::in, o3tl::Length::line), 60)); +static_assert(eq(o3tl::convert(13.0, o3tl::Length::ft, o3tl::Length::line), 720)); +static_assert(eq(o3tl::convert(13.0, o3tl::Length::mi, o3tl::Length::line), 3801600)); +static_assert(eq(o3tl::convert(624.0, o3tl::Length::master, o3tl::Length::line), 5)); +static_assert(eq(o3tl::convert(104.0, o3tl::Length::px, o3tl::Length::line), 5)); +static_assert(eq(o3tl::convert(52.0, o3tl::Length::ch, o3tl::Length::line), 35)); +static_assert(eq(o3tl::convert(1.0, o3tl::Length::line, o3tl::Length::line), 1)); + +// testing integral conversion + +static_assert(o3tl::convert(100, o3tl::Length::mm100, o3tl::Length::mm100) == 100); +static_assert(o3tl::convert(100, o3tl::Length::mm10, o3tl::Length::mm100) == 1000); +static_assert(o3tl::convert(100, o3tl::Length::mm, o3tl::Length::mm100) == 10000); +static_assert(o3tl::convert(100, o3tl::Length::cm, o3tl::Length::mm100) == 100000); +static_assert(o3tl::convert(100, o3tl::Length::m, o3tl::Length::mm100) == 10000000); +static_assert(o3tl::convert(100, o3tl::Length::km, o3tl::Length::mm100) == 10000000000); +static_assert(o3tl::convert(36000, o3tl::Length::emu, o3tl::Length::mm100) == 100); +static_assert(o3tl::convert(7200, o3tl::Length::twip, o3tl::Length::mm100) == 12700); +static_assert(o3tl::convert(1800, o3tl::Length::pt, o3tl::Length::mm100) == 63500); +static_assert(o3tl::convert(300, o3tl::Length::pc, o3tl::Length::mm100) == 127000); +static_assert(o3tl::convert(5000, o3tl::Length::in1000, o3tl::Length::mm100) == 12700); +static_assert(o3tl::convert(500, o3tl::Length::in100, o3tl::Length::mm100) == 12700); +static_assert(o3tl::convert(100, o3tl::Length::in10, o3tl::Length::mm100) == 25400); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::mm100) == 254000); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::mm100) == 3048000); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::mm100) == 16093440000); +static_assert(o3tl::convert(14400, o3tl::Length::master, o3tl::Length::mm100) == 63500); +static_assert(o3tl::convert(2400, o3tl::Length::px, o3tl::Length::mm100) == 63500); +static_assert(o3tl::convert(1200, o3tl::Length::ch, o3tl::Length::mm100) == 444500); +static_assert(o3tl::convert(300, o3tl::Length::line, o3tl::Length::mm100) == 165100); + +static_assert(o3tl::convert(1000, o3tl::Length::mm100, o3tl::Length::mm10) == 100); +static_assert(o3tl::convert(100, o3tl::Length::mm10, o3tl::Length::mm10) == 100); +static_assert(o3tl::convert(100, o3tl::Length::mm, o3tl::Length::mm10) == 1000); +static_assert(o3tl::convert(100, o3tl::Length::cm, o3tl::Length::mm10) == 10000); +static_assert(o3tl::convert(100, o3tl::Length::m, o3tl::Length::mm10) == 1000000); +static_assert(o3tl::convert(100, o3tl::Length::km, o3tl::Length::mm10) == 1000000000); +static_assert(o3tl::convert(360000, o3tl::Length::emu, o3tl::Length::mm10) == 100); +static_assert(o3tl::convert(72000, o3tl::Length::twip, o3tl::Length::mm10) == 12700); +static_assert(o3tl::convert(3600, o3tl::Length::pt, o3tl::Length::mm10) == 12700); +static_assert(o3tl::convert(300, o3tl::Length::pc, o3tl::Length::mm10) == 12700); +static_assert(o3tl::convert(50000, o3tl::Length::in1000, o3tl::Length::mm10) == 12700); +static_assert(o3tl::convert(5000, o3tl::Length::in100, o3tl::Length::mm10) == 12700); +static_assert(o3tl::convert(500, o3tl::Length::in10, o3tl::Length::mm10) == 12700); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::mm10) == 25400); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::mm10) == 304800); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::mm10) == 1609344000); +static_assert(o3tl::convert(28800, o3tl::Length::master, o3tl::Length::mm10) == 12700); +static_assert(o3tl::convert(4800, o3tl::Length::px, o3tl::Length::mm10) == 12700); +static_assert(o3tl::convert(2400, o3tl::Length::ch, o3tl::Length::mm10) == 88900); +static_assert(o3tl::convert(3000, o3tl::Length::line, o3tl::Length::mm10) == 165100); + +static_assert(o3tl::convert(10000, o3tl::Length::mm100, o3tl::Length::mm) == 100); +static_assert(o3tl::convert(1000, o3tl::Length::mm10, o3tl::Length::mm) == 100); +static_assert(o3tl::convert(100, o3tl::Length::mm, o3tl::Length::mm) == 100); +static_assert(o3tl::convert(100, o3tl::Length::cm, o3tl::Length::mm) == 1000); +static_assert(o3tl::convert(100, o3tl::Length::m, o3tl::Length::mm) == 100000); +static_assert(o3tl::convert(100, o3tl::Length::km, o3tl::Length::mm) == 100000000); +static_assert(o3tl::convert(3600000, o3tl::Length::emu, o3tl::Length::mm) == 100); +static_assert(o3tl::convert(720000, o3tl::Length::twip, o3tl::Length::mm) == 12700); +static_assert(o3tl::convert(36000, o3tl::Length::pt, o3tl::Length::mm) == 12700); +static_assert(o3tl::convert(3000, o3tl::Length::pc, o3tl::Length::mm) == 12700); +static_assert(o3tl::convert(500000, o3tl::Length::in1000, o3tl::Length::mm) == 12700); +static_assert(o3tl::convert(50000, o3tl::Length::in100, o3tl::Length::mm) == 12700); +static_assert(o3tl::convert(5000, o3tl::Length::in10, o3tl::Length::mm) == 12700); +static_assert(o3tl::convert(500, o3tl::Length::in, o3tl::Length::mm) == 12700); +static_assert(o3tl::convert(500, o3tl::Length::ft, o3tl::Length::mm) == 152400); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::mm) == 160934400); +static_assert(o3tl::convert(288000, o3tl::Length::master, o3tl::Length::mm) == 12700); +static_assert(o3tl::convert(48000, o3tl::Length::px, o3tl::Length::mm) == 12700); +static_assert(o3tl::convert(24000, o3tl::Length::ch, o3tl::Length::mm) == 88900); +static_assert(o3tl::convert(30000, o3tl::Length::line, o3tl::Length::mm) == 165100); + +static_assert(o3tl::convert(100000, o3tl::Length::mm100, o3tl::Length::cm) == 100); +static_assert(o3tl::convert(10000, o3tl::Length::mm10, o3tl::Length::cm) == 100); +static_assert(o3tl::convert(1000, o3tl::Length::mm, o3tl::Length::cm) == 100); +static_assert(o3tl::convert(100, o3tl::Length::cm, o3tl::Length::cm) == 100); +static_assert(o3tl::convert(100, o3tl::Length::m, o3tl::Length::cm) == 10000); +static_assert(o3tl::convert(100, o3tl::Length::km, o3tl::Length::cm) == 10000000); +static_assert(o3tl::convert(36000000, o3tl::Length::emu, o3tl::Length::cm) == 100); +static_assert(o3tl::convert(7200000, o3tl::Length::twip, o3tl::Length::cm) == 12700); +static_assert(o3tl::convert(360000, o3tl::Length::pt, o3tl::Length::cm) == 12700); +static_assert(o3tl::convert(30000, o3tl::Length::pc, o3tl::Length::cm) == 12700); +static_assert(o3tl::convert(5000000, o3tl::Length::in1000, o3tl::Length::cm) == 12700); +static_assert(o3tl::convert(500000, o3tl::Length::in100, o3tl::Length::cm) == 12700); +static_assert(o3tl::convert(50000, o3tl::Length::in10, o3tl::Length::cm) == 12700); +static_assert(o3tl::convert(5000, o3tl::Length::in, o3tl::Length::cm) == 12700); +static_assert(o3tl::convert(2500, o3tl::Length::ft, o3tl::Length::cm) == 76200); +static_assert(o3tl::convert(500, o3tl::Length::mi, o3tl::Length::cm) == 80467200); +static_assert(o3tl::convert(2880000, o3tl::Length::master, o3tl::Length::cm) == 12700); +static_assert(o3tl::convert(480000, o3tl::Length::px, o3tl::Length::cm) == 12700); +static_assert(o3tl::convert(240000, o3tl::Length::ch, o3tl::Length::cm) == 88900); +static_assert(o3tl::convert(300000, o3tl::Length::line, o3tl::Length::cm) == 165100); + +static_assert(o3tl::convert(10000000, o3tl::Length::mm100, o3tl::Length::m) == 100); +static_assert(o3tl::convert(1000000, o3tl::Length::mm10, o3tl::Length::m) == 100); +static_assert(o3tl::convert(100000, o3tl::Length::mm, o3tl::Length::m) == 100); +static_assert(o3tl::convert(10000, o3tl::Length::cm, o3tl::Length::m) == 100); +static_assert(o3tl::convert(100, o3tl::Length::m, o3tl::Length::m) == 100); +static_assert(o3tl::convert(100, o3tl::Length::km, o3tl::Length::m) == 100000); +static_assert(o3tl::convert(3600000000, o3tl::Length::emu, o3tl::Length::m) == 100); +static_assert(o3tl::convert(720000000, o3tl::Length::twip, o3tl::Length::m) == 12700); +static_assert(o3tl::convert(36000000, o3tl::Length::pt, o3tl::Length::m) == 12700); +static_assert(o3tl::convert(3000000, o3tl::Length::pc, o3tl::Length::m) == 12700); +static_assert(o3tl::convert(500000000, o3tl::Length::in1000, o3tl::Length::m) == 12700); +static_assert(o3tl::convert(50000000, o3tl::Length::in100, o3tl::Length::m) == 12700); +static_assert(o3tl::convert(5000000, o3tl::Length::in10, o3tl::Length::m) == 12700); +static_assert(o3tl::convert(500000, o3tl::Length::in, o3tl::Length::m) == 12700); +static_assert(o3tl::convert(125000, o3tl::Length::ft, o3tl::Length::m) == 38100); +static_assert(o3tl::convert(12500, o3tl::Length::mi, o3tl::Length::m) == 20116800); +static_assert(o3tl::convert(288000000, o3tl::Length::master, o3tl::Length::m) == 12700); +static_assert(o3tl::convert(48000000, o3tl::Length::px, o3tl::Length::m) == 12700); +static_assert(o3tl::convert(24000000, o3tl::Length::ch, o3tl::Length::m) == 88900); +static_assert(o3tl::convert(30000000, o3tl::Length::line, o3tl::Length::m) == 165100); + +static_assert(o3tl::convert(10000000000, o3tl::Length::mm100, o3tl::Length::km) == 100); +static_assert(o3tl::convert(1000000000, o3tl::Length::mm10, o3tl::Length::km) == 100); +static_assert(o3tl::convert(100000000, o3tl::Length::mm, o3tl::Length::km) == 100); +static_assert(o3tl::convert(10000000, o3tl::Length::cm, o3tl::Length::km) == 100); +static_assert(o3tl::convert(100000, o3tl::Length::m, o3tl::Length::km) == 100); +static_assert(o3tl::convert(100, o3tl::Length::km, o3tl::Length::km) == 100); +static_assert(o3tl::convert(3600000000000, o3tl::Length::emu, o3tl::Length::km) == 100); +static_assert(o3tl::convert(720000000000, o3tl::Length::twip, o3tl::Length::km) == 12700); +static_assert(o3tl::convert(36000000000, o3tl::Length::pt, o3tl::Length::km) == 12700); +static_assert(o3tl::convert(3000000000, o3tl::Length::pc, o3tl::Length::km) == 12700); +static_assert(o3tl::convert(500000000000, o3tl::Length::in1000, o3tl::Length::km) == 12700); +static_assert(o3tl::convert(50000000000, o3tl::Length::in100, o3tl::Length::km) == 12700); +static_assert(o3tl::convert(5000000000, o3tl::Length::in10, o3tl::Length::km) == 12700); +static_assert(o3tl::convert(500000000, o3tl::Length::in, o3tl::Length::km) == 12700); +static_assert(o3tl::convert(125000000, o3tl::Length::ft, o3tl::Length::km) == 38100); +static_assert(o3tl::convert(1562500, o3tl::Length::mi, o3tl::Length::km) == 2514600); +static_assert(o3tl::convert(288000000000, o3tl::Length::master, o3tl::Length::km) == 12700); +static_assert(o3tl::convert(48000000000, o3tl::Length::px, o3tl::Length::km) == 12700); +static_assert(o3tl::convert(24000000000, o3tl::Length::ch, o3tl::Length::km) == 88900); +static_assert(o3tl::convert(30000000000, o3tl::Length::line, o3tl::Length::km) == 165100); + +static_assert(o3tl::convert(100, o3tl::Length::mm100, o3tl::Length::emu) == 36000); +static_assert(o3tl::convert(100, o3tl::Length::mm10, o3tl::Length::emu) == 360000); +static_assert(o3tl::convert(100, o3tl::Length::mm, o3tl::Length::emu) == 3600000); +static_assert(o3tl::convert(100, o3tl::Length::cm, o3tl::Length::emu) == 36000000); +static_assert(o3tl::convert(100, o3tl::Length::m, o3tl::Length::emu) == 3600000000); +static_assert(o3tl::convert(100, o3tl::Length::km, o3tl::Length::emu) == 3600000000000); +static_assert(o3tl::convert(100, o3tl::Length::emu, o3tl::Length::emu) == 100); +static_assert(o3tl::convert(100, o3tl::Length::twip, o3tl::Length::emu) == 63500); +static_assert(o3tl::convert(100, o3tl::Length::pt, o3tl::Length::emu) == 1270000); +static_assert(o3tl::convert(100, o3tl::Length::pc, o3tl::Length::emu) == 15240000); +static_assert(o3tl::convert(500, o3tl::Length::in1000, o3tl::Length::emu) == 457200); +static_assert(o3tl::convert(100, o3tl::Length::in100, o3tl::Length::emu) == 914400); +static_assert(o3tl::convert(100, o3tl::Length::in10, o3tl::Length::emu) == 9144000); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::emu) == 91440000); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::emu) == 1097280000); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::emu) == 5793638400000); +static_assert(o3tl::convert(200, o3tl::Length::master, o3tl::Length::emu) == 317500); +static_assert(o3tl::convert(100, o3tl::Length::px, o3tl::Length::emu) == 952500); +static_assert(o3tl::convert(100, o3tl::Length::ch, o3tl::Length::emu) == 13335000); +static_assert(o3tl::convert(100, o3tl::Length::line, o3tl::Length::emu) == 19812000); + +static_assert(o3tl::convert(12700, o3tl::Length::mm100, o3tl::Length::twip) == 7200); +static_assert(o3tl::convert(12700, o3tl::Length::mm10, o3tl::Length::twip) == 72000); +static_assert(o3tl::convert(12700, o3tl::Length::mm, o3tl::Length::twip) == 720000); +static_assert(o3tl::convert(12700, o3tl::Length::cm, o3tl::Length::twip) == 7200000); +static_assert(o3tl::convert(12700, o3tl::Length::m, o3tl::Length::twip) == 720000000); +static_assert(o3tl::convert(12700, o3tl::Length::km, o3tl::Length::twip) == 720000000000); +static_assert(o3tl::convert(63500, o3tl::Length::emu, o3tl::Length::twip) == 100); +static_assert(o3tl::convert(100, o3tl::Length::twip, o3tl::Length::twip) == 100); +static_assert(o3tl::convert(100, o3tl::Length::pt, o3tl::Length::twip) == 2000); +static_assert(o3tl::convert(100, o3tl::Length::pc, o3tl::Length::twip) == 24000); +static_assert(o3tl::convert(2500, o3tl::Length::in1000, o3tl::Length::twip) == 3600); +static_assert(o3tl::convert(500, o3tl::Length::in100, o3tl::Length::twip) == 7200); +static_assert(o3tl::convert(100, o3tl::Length::in10, o3tl::Length::twip) == 14400); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::twip) == 144000); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::twip) == 1728000); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::twip) == 9123840000); +static_assert(o3tl::convert(200, o3tl::Length::master, o3tl::Length::twip) == 500); +static_assert(o3tl::convert(100, o3tl::Length::px, o3tl::Length::twip) == 1500); +static_assert(o3tl::convert(100, o3tl::Length::ch, o3tl::Length::twip) == 21000); +static_assert(o3tl::convert(100, o3tl::Length::line, o3tl::Length::twip) == 31200); + +static_assert(o3tl::convert(63500, o3tl::Length::mm100, o3tl::Length::pt) == 1800); +static_assert(o3tl::convert(12700, o3tl::Length::mm10, o3tl::Length::pt) == 3600); +static_assert(o3tl::convert(12700, o3tl::Length::mm, o3tl::Length::pt) == 36000); +static_assert(o3tl::convert(12700, o3tl::Length::cm, o3tl::Length::pt) == 360000); +static_assert(o3tl::convert(12700, o3tl::Length::m, o3tl::Length::pt) == 36000000); +static_assert(o3tl::convert(12700, o3tl::Length::km, o3tl::Length::pt) == 36000000000); +static_assert(o3tl::convert(1270000, o3tl::Length::emu, o3tl::Length::pt) == 100); +static_assert(o3tl::convert(2000, o3tl::Length::twip, o3tl::Length::pt) == 100); +static_assert(o3tl::convert(100, o3tl::Length::pt, o3tl::Length::pt) == 100); +static_assert(o3tl::convert(100, o3tl::Length::pc, o3tl::Length::pt) == 1200); +static_assert(o3tl::convert(12500, o3tl::Length::in1000, o3tl::Length::pt) == 900); +static_assert(o3tl::convert(2500, o3tl::Length::in100, o3tl::Length::pt) == 1800); +static_assert(o3tl::convert(500, o3tl::Length::in10, o3tl::Length::pt) == 3600); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::pt) == 7200); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::pt) == 86400); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::pt) == 456192000); +static_assert(o3tl::convert(800, o3tl::Length::master, o3tl::Length::pt) == 100); +static_assert(o3tl::convert(400, o3tl::Length::px, o3tl::Length::pt) == 300); +static_assert(o3tl::convert(200, o3tl::Length::ch, o3tl::Length::pt) == 2100); +static_assert(o3tl::convert(500, o3tl::Length::line, o3tl::Length::pt) == 7800); + +static_assert(o3tl::convert(127000, o3tl::Length::mm100, o3tl::Length::pc) == 300); +static_assert(o3tl::convert(12700, o3tl::Length::mm10, o3tl::Length::pc) == 300); +static_assert(o3tl::convert(12700, o3tl::Length::mm, o3tl::Length::pc) == 3000); +static_assert(o3tl::convert(12700, o3tl::Length::cm, o3tl::Length::pc) == 30000); +static_assert(o3tl::convert(12700, o3tl::Length::m, o3tl::Length::pc) == 3000000); +static_assert(o3tl::convert(12700, o3tl::Length::km, o3tl::Length::pc) == 3000000000); +static_assert(o3tl::convert(15240000, o3tl::Length::emu, o3tl::Length::pc) == 100); +static_assert(o3tl::convert(24000, o3tl::Length::twip, o3tl::Length::pc) == 100); +static_assert(o3tl::convert(1200, o3tl::Length::pt, o3tl::Length::pc) == 100); +static_assert(o3tl::convert(100, o3tl::Length::pc, o3tl::Length::pc) == 100); +static_assert(o3tl::convert(50000, o3tl::Length::in1000, o3tl::Length::pc) == 300); +static_assert(o3tl::convert(5000, o3tl::Length::in100, o3tl::Length::pc) == 300); +static_assert(o3tl::convert(500, o3tl::Length::in10, o3tl::Length::pc) == 300); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::pc) == 600); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::pc) == 7200); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::pc) == 38016000); +static_assert(o3tl::convert(9600, o3tl::Length::master, o3tl::Length::pc) == 100); +static_assert(o3tl::convert(1600, o3tl::Length::px, o3tl::Length::pc) == 100); +static_assert(o3tl::convert(800, o3tl::Length::ch, o3tl::Length::pc) == 700); +static_assert(o3tl::convert(1000, o3tl::Length::line, o3tl::Length::pc) == 1300); + +static_assert(o3tl::convert(12700, o3tl::Length::mm100, o3tl::Length::in1000) == 5000); +static_assert(o3tl::convert(12700, o3tl::Length::mm10, o3tl::Length::in1000) == 50000); +static_assert(o3tl::convert(12700, o3tl::Length::mm, o3tl::Length::in1000) == 500000); +static_assert(o3tl::convert(12700, o3tl::Length::cm, o3tl::Length::in1000) == 5000000); +static_assert(o3tl::convert(12700, o3tl::Length::m, o3tl::Length::in1000) == 500000000); +static_assert(o3tl::convert(12700, o3tl::Length::km, o3tl::Length::in1000) == 500000000000); +static_assert(o3tl::convert(457200, o3tl::Length::emu, o3tl::Length::in1000) == 500); +static_assert(o3tl::convert(3600, o3tl::Length::twip, o3tl::Length::in1000) == 2500); +static_assert(o3tl::convert(900, o3tl::Length::pt, o3tl::Length::in1000) == 12500); +static_assert(o3tl::convert(300, o3tl::Length::pc, o3tl::Length::in1000) == 50000); +static_assert(o3tl::convert(100, o3tl::Length::in1000, o3tl::Length::in1000) == 100); +static_assert(o3tl::convert(100, o3tl::Length::in100, o3tl::Length::in1000) == 1000); +static_assert(o3tl::convert(100, o3tl::Length::in10, o3tl::Length::in1000) == 10000); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::in1000) == 100000); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::in1000) == 1200000); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::in1000) == 6336000000); +static_assert(o3tl::convert(7200, o3tl::Length::master, o3tl::Length::in1000) == 12500); +static_assert(o3tl::convert(1200, o3tl::Length::px, o3tl::Length::in1000) == 12500); +static_assert(o3tl::convert(600, o3tl::Length::ch, o3tl::Length::in1000) == 87500); +static_assert(o3tl::convert(300, o3tl::Length::line, o3tl::Length::in1000) == 65000); + +static_assert(o3tl::convert(12700, o3tl::Length::mm100, o3tl::Length::in100) == 500); +static_assert(o3tl::convert(12700, o3tl::Length::mm10, o3tl::Length::in100) == 5000); +static_assert(o3tl::convert(12700, o3tl::Length::mm, o3tl::Length::in100) == 50000); +static_assert(o3tl::convert(12700, o3tl::Length::cm, o3tl::Length::in100) == 500000); +static_assert(o3tl::convert(12700, o3tl::Length::m, o3tl::Length::in100) == 50000000); +static_assert(o3tl::convert(12700, o3tl::Length::km, o3tl::Length::in100) == 50000000000); +static_assert(o3tl::convert(914400, o3tl::Length::emu, o3tl::Length::in100) == 100); +static_assert(o3tl::convert(7200, o3tl::Length::twip, o3tl::Length::in100) == 500); +static_assert(o3tl::convert(1800, o3tl::Length::pt, o3tl::Length::in100) == 2500); +static_assert(o3tl::convert(300, o3tl::Length::pc, o3tl::Length::in100) == 5000); +static_assert(o3tl::convert(1000, o3tl::Length::in1000, o3tl::Length::in100) == 100); +static_assert(o3tl::convert(100, o3tl::Length::in100, o3tl::Length::in100) == 100); +static_assert(o3tl::convert(100, o3tl::Length::in10, o3tl::Length::in100) == 1000); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::in100) == 10000); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::in100) == 120000); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::in100) == 633600000); +static_assert(o3tl::convert(14400, o3tl::Length::master, o3tl::Length::in100) == 2500); +static_assert(o3tl::convert(2400, o3tl::Length::px, o3tl::Length::in100) == 2500); +static_assert(o3tl::convert(1200, o3tl::Length::ch, o3tl::Length::in100) == 17500); +static_assert(o3tl::convert(300, o3tl::Length::line, o3tl::Length::in100) == 6500); + +static_assert(o3tl::convert(25400, o3tl::Length::mm100, o3tl::Length::in10) == 100); +static_assert(o3tl::convert(12700, o3tl::Length::mm10, o3tl::Length::in10) == 500); +static_assert(o3tl::convert(12700, o3tl::Length::mm, o3tl::Length::in10) == 5000); +static_assert(o3tl::convert(12700, o3tl::Length::cm, o3tl::Length::in10) == 50000); +static_assert(o3tl::convert(12700, o3tl::Length::m, o3tl::Length::in10) == 5000000); +static_assert(o3tl::convert(12700, o3tl::Length::km, o3tl::Length::in10) == 5000000000); +static_assert(o3tl::convert(9144000, o3tl::Length::emu, o3tl::Length::in10) == 100); +static_assert(o3tl::convert(14400, o3tl::Length::twip, o3tl::Length::in10) == 100); +static_assert(o3tl::convert(3600, o3tl::Length::pt, o3tl::Length::in10) == 500); +static_assert(o3tl::convert(300, o3tl::Length::pc, o3tl::Length::in10) == 500); +static_assert(o3tl::convert(10000, o3tl::Length::in1000, o3tl::Length::in10) == 100); +static_assert(o3tl::convert(1000, o3tl::Length::in100, o3tl::Length::in10) == 100); +static_assert(o3tl::convert(100, o3tl::Length::in10, o3tl::Length::in10) == 100); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::in10) == 1000); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::in10) == 12000); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::in10) == 63360000); +static_assert(o3tl::convert(28800, o3tl::Length::master, o3tl::Length::in10) == 500); +static_assert(o3tl::convert(4800, o3tl::Length::px, o3tl::Length::in10) == 500); +static_assert(o3tl::convert(2400, o3tl::Length::ch, o3tl::Length::in10) == 3500); +static_assert(o3tl::convert(600, o3tl::Length::line, o3tl::Length::in10) == 1300); + +static_assert(o3tl::convert(254000, o3tl::Length::mm100, o3tl::Length::in) == 100); +static_assert(o3tl::convert(25400, o3tl::Length::mm10, o3tl::Length::in) == 100); +static_assert(o3tl::convert(12700, o3tl::Length::mm, o3tl::Length::in) == 500); +static_assert(o3tl::convert(12700, o3tl::Length::cm, o3tl::Length::in) == 5000); +static_assert(o3tl::convert(12700, o3tl::Length::m, o3tl::Length::in) == 500000); +static_assert(o3tl::convert(12700, o3tl::Length::km, o3tl::Length::in) == 500000000); +static_assert(o3tl::convert(91440000, o3tl::Length::emu, o3tl::Length::in) == 100); +static_assert(o3tl::convert(144000, o3tl::Length::twip, o3tl::Length::in) == 100); +static_assert(o3tl::convert(7200, o3tl::Length::pt, o3tl::Length::in) == 100); +static_assert(o3tl::convert(600, o3tl::Length::pc, o3tl::Length::in) == 100); +static_assert(o3tl::convert(100000, o3tl::Length::in1000, o3tl::Length::in) == 100); +static_assert(o3tl::convert(10000, o3tl::Length::in100, o3tl::Length::in) == 100); +static_assert(o3tl::convert(1000, o3tl::Length::in10, o3tl::Length::in) == 100); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::in) == 100); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::in) == 1200); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::in) == 6336000); +static_assert(o3tl::convert(57600, o3tl::Length::master, o3tl::Length::in) == 100); +static_assert(o3tl::convert(9600, o3tl::Length::px, o3tl::Length::in) == 100); +static_assert(o3tl::convert(4800, o3tl::Length::ch, o3tl::Length::in) == 700); +static_assert(o3tl::convert(6000, o3tl::Length::line, o3tl::Length::in) == 1300); + +static_assert(o3tl::convert(3048000, o3tl::Length::mm100, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(304800, o3tl::Length::mm10, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(152400, o3tl::Length::mm, o3tl::Length::ft) == 500); +static_assert(o3tl::convert(76200, o3tl::Length::cm, o3tl::Length::ft) == 2500); +static_assert(o3tl::convert(38100, o3tl::Length::m, o3tl::Length::ft) == 125000); +static_assert(o3tl::convert(38100, o3tl::Length::km, o3tl::Length::ft) == 125000000); +static_assert(o3tl::convert(1097280000, o3tl::Length::emu, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(1728000, o3tl::Length::twip, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(86400, o3tl::Length::pt, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(7200, o3tl::Length::pc, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(1200000, o3tl::Length::in1000, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(120000, o3tl::Length::in100, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(12000, o3tl::Length::in10, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(1200, o3tl::Length::in, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::ft) == 528000); +static_assert(o3tl::convert(691200, o3tl::Length::master, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(115200, o3tl::Length::px, o3tl::Length::ft) == 100); +static_assert(o3tl::convert(57600, o3tl::Length::ch, o3tl::Length::ft) == 700); +static_assert(o3tl::convert(72000, o3tl::Length::line, o3tl::Length::ft) == 1300); + +static_assert(o3tl::convert(16093440000, o3tl::Length::mm100, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(1609344000, o3tl::Length::mm10, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(160934400, o3tl::Length::mm, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(80467200, o3tl::Length::cm, o3tl::Length::mi) == 500); +static_assert(o3tl::convert(20116800, o3tl::Length::m, o3tl::Length::mi) == 12500); +static_assert(o3tl::convert(2514600, o3tl::Length::km, o3tl::Length::mi) == 1562500); +static_assert(o3tl::convert(5793638400000, o3tl::Length::emu, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(9123840000, o3tl::Length::twip, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(456192000, o3tl::Length::pt, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(38016000, o3tl::Length::pc, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(6336000000, o3tl::Length::in1000, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(633600000, o3tl::Length::in100, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(63360000, o3tl::Length::in10, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(6336000, o3tl::Length::in, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(528000, o3tl::Length::ft, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(3649536000, o3tl::Length::master, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(608256000, o3tl::Length::px, o3tl::Length::mi) == 100); +static_assert(o3tl::convert(304128000, o3tl::Length::ch, o3tl::Length::mi) == 700); +static_assert(o3tl::convert(380160000, o3tl::Length::line, o3tl::Length::mi) == 1300); + +static_assert(o3tl::convert(63500, o3tl::Length::mm100, o3tl::Length::master) == 14400); +static_assert(o3tl::convert(12700, o3tl::Length::mm10, o3tl::Length::master) == 28800); +static_assert(o3tl::convert(12700, o3tl::Length::mm, o3tl::Length::master) == 288000); +static_assert(o3tl::convert(12700, o3tl::Length::cm, o3tl::Length::master) == 2880000); +static_assert(o3tl::convert(12700, o3tl::Length::m, o3tl::Length::master) == 288000000); +static_assert(o3tl::convert(12700, o3tl::Length::km, o3tl::Length::master) == 288000000000); +static_assert(o3tl::convert(317500, o3tl::Length::emu, o3tl::Length::master) == 200); +static_assert(o3tl::convert(500, o3tl::Length::twip, o3tl::Length::master) == 200); +static_assert(o3tl::convert(100, o3tl::Length::pt, o3tl::Length::master) == 800); +static_assert(o3tl::convert(100, o3tl::Length::pc, o3tl::Length::master) == 9600); +static_assert(o3tl::convert(12500, o3tl::Length::in1000, o3tl::Length::master) == 7200); +static_assert(o3tl::convert(2500, o3tl::Length::in100, o3tl::Length::master) == 14400); +static_assert(o3tl::convert(500, o3tl::Length::in10, o3tl::Length::master) == 28800); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::master) == 57600); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::master) == 691200); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::master) == 3649536000); +static_assert(o3tl::convert(100, o3tl::Length::master, o3tl::Length::master) == 100); +static_assert(o3tl::convert(100, o3tl::Length::px, o3tl::Length::master) == 600); +static_assert(o3tl::convert(100, o3tl::Length::ch, o3tl::Length::master) == 8400); +static_assert(o3tl::convert(500, o3tl::Length::line, o3tl::Length::master) == 62400); + +static_assert(o3tl::convert(63500, o3tl::Length::mm100, o3tl::Length::px) == 2400); +static_assert(o3tl::convert(12700, o3tl::Length::mm10, o3tl::Length::px) == 4800); +static_assert(o3tl::convert(12700, o3tl::Length::mm, o3tl::Length::px) == 48000); +static_assert(o3tl::convert(12700, o3tl::Length::cm, o3tl::Length::px) == 480000); +static_assert(o3tl::convert(12700, o3tl::Length::m, o3tl::Length::px) == 48000000); +static_assert(o3tl::convert(12700, o3tl::Length::km, o3tl::Length::px) == 48000000000); +static_assert(o3tl::convert(952500, o3tl::Length::emu, o3tl::Length::px) == 100); +static_assert(o3tl::convert(1500, o3tl::Length::twip, o3tl::Length::px) == 100); +static_assert(o3tl::convert(300, o3tl::Length::pt, o3tl::Length::px) == 400); +static_assert(o3tl::convert(100, o3tl::Length::pc, o3tl::Length::px) == 1600); +static_assert(o3tl::convert(12500, o3tl::Length::in1000, o3tl::Length::px) == 1200); +static_assert(o3tl::convert(2500, o3tl::Length::in100, o3tl::Length::px) == 2400); +static_assert(o3tl::convert(500, o3tl::Length::in10, o3tl::Length::px) == 4800); +static_assert(o3tl::convert(100, o3tl::Length::in, o3tl::Length::px) == 9600); +static_assert(o3tl::convert(100, o3tl::Length::ft, o3tl::Length::px) == 115200); +static_assert(o3tl::convert(100, o3tl::Length::mi, o3tl::Length::px) == 608256000); +static_assert(o3tl::convert(600, o3tl::Length::master, o3tl::Length::px) == 100); +static_assert(o3tl::convert(100, o3tl::Length::px, o3tl::Length::px) == 100); +static_assert(o3tl::convert(100, o3tl::Length::ch, o3tl::Length::px) == 1400); +static_assert(o3tl::convert(500, o3tl::Length::line, o3tl::Length::px) == 10400); + +static_assert(o3tl::convert(444500, o3tl::Length::mm100, o3tl::Length::ch) == 1200); +static_assert(o3tl::convert(88900, o3tl::Length::mm10, o3tl::Length::ch) == 2400); +static_assert(o3tl::convert(88900, o3tl::Length::mm, o3tl::Length::ch) == 24000); +static_assert(o3tl::convert(88900, o3tl::Length::cm, o3tl::Length::ch) == 240000); +static_assert(o3tl::convert(88900, o3tl::Length::m, o3tl::Length::ch) == 24000000); +static_assert(o3tl::convert(88900, o3tl::Length::km, o3tl::Length::ch) == 24000000000); +static_assert(o3tl::convert(13335000, o3tl::Length::emu, o3tl::Length::ch) == 100); +static_assert(o3tl::convert(21000, o3tl::Length::twip, o3tl::Length::ch) == 100); +static_assert(o3tl::convert(2100, o3tl::Length::pt, o3tl::Length::ch) == 200); +static_assert(o3tl::convert(700, o3tl::Length::pc, o3tl::Length::ch) == 800); +static_assert(o3tl::convert(87500, o3tl::Length::in1000, o3tl::Length::ch) == 600); +static_assert(o3tl::convert(17500, o3tl::Length::in100, o3tl::Length::ch) == 1200); +static_assert(o3tl::convert(3500, o3tl::Length::in10, o3tl::Length::ch) == 2400); +static_assert(o3tl::convert(700, o3tl::Length::in, o3tl::Length::ch) == 4800); +static_assert(o3tl::convert(700, o3tl::Length::ft, o3tl::Length::ch) == 57600); +static_assert(o3tl::convert(700, o3tl::Length::mi, o3tl::Length::ch) == 304128000); +static_assert(o3tl::convert(8400, o3tl::Length::master, o3tl::Length::ch) == 100); +static_assert(o3tl::convert(1400, o3tl::Length::px, o3tl::Length::ch) == 100); +static_assert(o3tl::convert(100, o3tl::Length::ch, o3tl::Length::ch) == 100); +static_assert(o3tl::convert(3500, o3tl::Length::line, o3tl::Length::ch) == 5200); + +static_assert(o3tl::convert(165100, o3tl::Length::mm100, o3tl::Length::line) == 300); +static_assert(o3tl::convert(165100, o3tl::Length::mm10, o3tl::Length::line) == 3000); +static_assert(o3tl::convert(165100, o3tl::Length::mm, o3tl::Length::line) == 30000); +static_assert(o3tl::convert(165100, o3tl::Length::cm, o3tl::Length::line) == 300000); +static_assert(o3tl::convert(165100, o3tl::Length::m, o3tl::Length::line) == 30000000); +static_assert(o3tl::convert(165100, o3tl::Length::km, o3tl::Length::line) == 30000000000); +static_assert(o3tl::convert(19812000, o3tl::Length::emu, o3tl::Length::line) == 100); +static_assert(o3tl::convert(31200, o3tl::Length::twip, o3tl::Length::line) == 100); +static_assert(o3tl::convert(7800, o3tl::Length::pt, o3tl::Length::line) == 500); +static_assert(o3tl::convert(1300, o3tl::Length::pc, o3tl::Length::line) == 1000); +static_assert(o3tl::convert(65000, o3tl::Length::in1000, o3tl::Length::line) == 300); +static_assert(o3tl::convert(6500, o3tl::Length::in100, o3tl::Length::line) == 300); +static_assert(o3tl::convert(1300, o3tl::Length::in10, o3tl::Length::line) == 600); +static_assert(o3tl::convert(1300, o3tl::Length::in, o3tl::Length::line) == 6000); +static_assert(o3tl::convert(1300, o3tl::Length::ft, o3tl::Length::line) == 72000); +static_assert(o3tl::convert(1300, o3tl::Length::mi, o3tl::Length::line) == 380160000); +static_assert(o3tl::convert(62400, o3tl::Length::master, o3tl::Length::line) == 500); +static_assert(o3tl::convert(10400, o3tl::Length::px, o3tl::Length::line) == 500); +static_assert(o3tl::convert(5200, o3tl::Length::ch, o3tl::Length::line) == 3500); +static_assert(o3tl::convert(100, o3tl::Length::line, o3tl::Length::line) == 100); + +// Integral rounding + +static_assert(o3tl::convert(49, o3tl::Length::mm100, o3tl::Length::mm) == 0); +static_assert(o3tl::convert(50, o3tl::Length::mm100, o3tl::Length::mm) == 1); + +// Conversions used in the code - to make sure they produce the expected and unchanged result + +static_assert(o3tl::toTwips(25, o3tl::Length::in100) == 1440 / 4); +static_assert(o3tl::toTwips(15, o3tl::Length::in100) == 216); +// the following twip value used to the constant for 20mm +static_assert(o3tl::toTwips(20, o3tl::Length::mm) == 1134); +// 847 100thmm used to represent 24pt +static_assert(o3tl::convert(24, o3tl::Length::pt, o3tl::Length::mm100) == 847); + +static_assert(o3tl::convertSaturate(SAL_MAX_INT64, 72, 127) == 5228998320106644552); // no overflow + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/o3tl/qa/test-vector_pool.cxx b/o3tl/qa/test-vector_pool.cxx new file mode 100644 index 0000000000..6e739ebcd1 --- /dev/null +++ b/o3tl/qa/test-vector_pool.cxx @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include <o3tl/vector_pool.hxx> + +using namespace ::o3tl; + +class vector_pool_test : public CppUnit::TestFixture +{ +public: + void testPoolBasics() + { + vector_pool<int> aPool; + + std::ptrdiff_t nIdx1 = aPool.alloc(); + std::ptrdiff_t nIdx2 = aPool.alloc(); + std::ptrdiff_t nIdx3 = aPool.alloc(); + + CPPUNIT_ASSERT_MESSAGE("allocator idx order 1", nIdx1 < nIdx2 ); + CPPUNIT_ASSERT_MESSAGE("allocator idx order 2", nIdx2 < nIdx3 ); + + aPool.free(nIdx2); + aPool.free(nIdx3); + + nIdx2 = aPool.alloc(); + nIdx3 = aPool.alloc(); + + CPPUNIT_ASSERT_MESSAGE("allocator idx order 1 after fragmentation", nIdx1 < nIdx3 ); + CPPUNIT_ASSERT_MESSAGE("allocator idx order 2 after fragmentation", nIdx3 < nIdx2 ); + } + + void testPoolValueSemantics() + { + vector_pool<int> aPool; + + std::ptrdiff_t nIdx1 = aPool.store(0); + CPPUNIT_ASSERT_EQUAL_MESSAGE("allocator value semantics 1", 0, aPool.get(nIdx1) ); + + std::ptrdiff_t nIdx2 = aPool.store(1); + CPPUNIT_ASSERT_EQUAL_MESSAGE("allocator value semantics 2", 1, aPool.get(nIdx2) ); + + std::ptrdiff_t nIdx3 = aPool.store(2); + CPPUNIT_ASSERT_EQUAL_MESSAGE("allocator value semantics 3", 2, aPool.get(nIdx3) ); + + aPool.free(nIdx2); + aPool.free(nIdx3); + + nIdx2 = aPool.store(1); + CPPUNIT_ASSERT_EQUAL_MESSAGE("allocator value semantics 2 after fragmentation", 1, aPool.get(nIdx2) ); + + nIdx3 = aPool.store(2); + CPPUNIT_ASSERT_EQUAL_MESSAGE("allocator value semantics 3 after fragmentation", 2, aPool.get(nIdx3) ); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(vector_pool_test); + CPPUNIT_TEST(testPoolBasics); + CPPUNIT_TEST(testPoolValueSemantics); + CPPUNIT_TEST_SUITE_END(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(vector_pool_test); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |