/** @file
 * @brief test common features of API classes
 */
/* Warning: This file is generated by ./generate-api_generated - do not modify directly! */
/* Copyright (C) 2007-2026 Olly Betts
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see
 * <https://www.gnu.org/licenses/>.
 */

#include <config.h>

#include "api_generated.h"

#define XAPIAN_DEPRECATED(D) D
#include <xapian.h>

#include "apitest.h"
#include "testutils.h"

using namespace std;

/// Check uncopyable API classes which should have a default ctor actually do.
DEFINE_TESTCASE(defaultctor1, !backend) {
    Xapian::BB2Weight bb2weight;
    Xapian::BM25PlusWeight bm25plusweight;
    Xapian::BM25Weight bm25weight;
    Xapian::BoolWeight boolweight;
    Xapian::CoordWeight coordweight;
    Xapian::DLHWeight dlhweight;
    Xapian::DPHWeight dphweight;
    Xapian::DateRangeProcessor daterangeprocessor(0);
    Xapian::DecreasingValueWeightPostingSource decreasingvalueweightpostingsource(0);
    {
	const string& desc = decreasingvalueweightpostingsource.get_description();
	tout.clear();
	tout << desc << '\n';
	TEST(startswith(desc, "DecreasingValueWeightPostingSource(") ||
	     startswith(desc, "Xapian::DecreasingValueWeightPostingSource("));
	TEST(desc.back() == ')');
    }
    Xapian::DiceWeight diceweight;
    Xapian::FixedWeightPostingSource fixedweightpostingsource(0);
    {
	const string& desc = fixedweightpostingsource.get_description();
	tout.clear();
	tout << desc << '\n';
	TEST(startswith(desc, "FixedWeightPostingSource(") ||
	     startswith(desc, "Xapian::FixedWeightPostingSource("));
	TEST(desc.back() == ')');
    }
    Xapian::IfB2Weight ifb2weight;
    Xapian::InL2Weight inl2weight;
    Xapian::IneB2Weight ineb2weight;
    Xapian::LM2StageWeight lm2stageweight;
    Xapian::LMAbsDiscountWeight lmabsdiscountweight;
    Xapian::LMDirichletWeight lmdirichletweight;
    Xapian::LMJMWeight lmjmweight;
    Xapian::MultiValueKeyMaker multivaluekeymaker;
    Xapian::NumberRangeProcessor numberrangeprocessor(0, "");
    Xapian::PL2PlusWeight pl2plusweight;
    Xapian::PL2Weight pl2weight;
    Xapian::RangeProcessor rangeprocessor;
    Xapian::SimpleStopper simplestopper;
    {
	const string& desc = simplestopper.get_description();
	tout.clear();
	tout << desc << '\n';
	TEST(startswith(desc, "SimpleStopper(") ||
	     startswith(desc, "Xapian::SimpleStopper("));
	TEST(desc.back() == ')');
    }
    Xapian::TfIdfWeight tfidfweight;
    Xapian::TradWeight tradweight;
    Xapian::ValueCountMatchSpy valuecountmatchspy(0);
    {
	const string& desc = valuecountmatchspy.get_description();
	tout.clear();
	tout << desc << '\n';
	TEST(startswith(desc, "ValueCountMatchSpy(") ||
	     startswith(desc, "Xapian::ValueCountMatchSpy("));
	TEST(desc.back() == ')');
    }
    Xapian::ValueMapPostingSource valuemappostingsource(0);
    {
	const string& desc = valuemappostingsource.get_description();
	tout.clear();
	tout << desc << '\n';
	TEST(startswith(desc, "ValueMapPostingSource(") ||
	     startswith(desc, "Xapian::ValueMapPostingSource("));
	TEST(desc.back() == ')');
    }
    Xapian::ValuePostingSource valuepostingsource(0);
    {
	const string& desc = valuepostingsource.get_description();
	tout.clear();
	tout << desc << '\n';
	TEST(startswith(desc, "ValuePostingSource(") ||
	     startswith(desc, "Xapian::ValuePostingSource("));
	TEST(desc.back() == ')');
    }
    Xapian::ValueWeightPostingSource valueweightpostingsource(0);
    {
	const string& desc = valueweightpostingsource.get_description();
	tout.clear();
	tout << desc << '\n';
	TEST(startswith(desc, "ValueWeightPostingSource(") ||
	     startswith(desc, "Xapian::ValueWeightPostingSource("));
	TEST(desc.back() == ')');
    }
}

/// Test that API classes have a copy ctor and assignment operator.
DEFINE_TESTCASE(copyassign1, !backend) {
    Xapian::Database database;
    TEST(!database.get_description().empty());
    Xapian::Database copy_database(database);
    TEST(!copy_database.get_description().empty());
    Xapian::Database move_database(std::move(database));
    TEST(!move_database.get_description().empty());
    database = copy_database;
    TEST(!database.get_description().empty());
    copy_database = std::move(move_database);
    TEST(!copy_database.get_description().empty());

    Xapian::Document document;
    TEST(!document.get_description().empty());
    Xapian::Document copy_document(document);
    TEST(!copy_document.get_description().empty());
    Xapian::Document move_document(std::move(document));
    TEST(!move_document.get_description().empty());
    document = copy_document;
    TEST(!document.get_description().empty());
    copy_document = std::move(move_document);
    TEST(!copy_document.get_description().empty());

    Xapian::ESet eset;
    TEST(!eset.get_description().empty());
    Xapian::ESet copy_eset(eset);
    TEST(!copy_eset.get_description().empty());
    Xapian::ESet move_eset(std::move(eset));
    TEST(!move_eset.get_description().empty());
    eset = copy_eset;
    TEST(!eset.get_description().empty());
    copy_eset = std::move(move_eset);
    TEST(!copy_eset.get_description().empty());

    Xapian::ESetIterator esetiterator;
    TEST(!esetiterator.get_description().empty());
    Xapian::ESetIterator copy_esetiterator(esetiterator);
    TEST(!copy_esetiterator.get_description().empty());
    Xapian::ESetIterator move_esetiterator(std::move(esetiterator));
    TEST(!move_esetiterator.get_description().empty());
    esetiterator = copy_esetiterator;
    TEST(!esetiterator.get_description().empty());
    copy_esetiterator = std::move(move_esetiterator);
    TEST(!copy_esetiterator.get_description().empty());

#ifdef XAPIAN_HAS_INMEMORY_BACKEND
    Xapian::Enquire enquire(Xapian::Database(std::string(), Xapian::DB_BACKEND_INMEMORY));
    TEST(!enquire.get_description().empty());
    Xapian::Enquire copy_enquire(enquire);
    TEST(!copy_enquire.get_description().empty());
    Xapian::Enquire move_enquire(std::move(enquire));
    TEST(!move_enquire.get_description().empty());
    enquire = copy_enquire;
    TEST(!enquire.get_description().empty());
    copy_enquire = std::move(move_enquire);
    TEST(!copy_enquire.get_description().empty());
#endif

    Xapian::MSet mset;
    TEST(!mset.get_description().empty());
    Xapian::MSet copy_mset(mset);
    TEST(!copy_mset.get_description().empty());
    Xapian::MSet move_mset(std::move(mset));
    TEST(!move_mset.get_description().empty());
    mset = copy_mset;
    TEST(!mset.get_description().empty());
    copy_mset = std::move(move_mset);
    TEST(!copy_mset.get_description().empty());

    Xapian::MSetIterator msetiterator;
    TEST(!msetiterator.get_description().empty());
    Xapian::MSetIterator copy_msetiterator(msetiterator);
    TEST(!copy_msetiterator.get_description().empty());
    Xapian::MSetIterator move_msetiterator(std::move(msetiterator));
    TEST(!move_msetiterator.get_description().empty());
    msetiterator = copy_msetiterator;
    TEST(!msetiterator.get_description().empty());
    copy_msetiterator = std::move(move_msetiterator);
    TEST(!copy_msetiterator.get_description().empty());

    Xapian::PositionIterator positioniterator;
    TEST(!positioniterator.get_description().empty());
    Xapian::PositionIterator copy_positioniterator(positioniterator);
    TEST(!copy_positioniterator.get_description().empty());
    Xapian::PositionIterator move_positioniterator(std::move(positioniterator));
    TEST(!move_positioniterator.get_description().empty());
    positioniterator = copy_positioniterator;
    TEST(!positioniterator.get_description().empty());
    copy_positioniterator = std::move(move_positioniterator);
    TEST(!copy_positioniterator.get_description().empty());

    Xapian::PostingIterator postingiterator;
    TEST(!postingiterator.get_description().empty());
    Xapian::PostingIterator copy_postingiterator(postingiterator);
    TEST(!copy_postingiterator.get_description().empty());
    Xapian::PostingIterator move_postingiterator(std::move(postingiterator));
    TEST(!move_postingiterator.get_description().empty());
    postingiterator = copy_postingiterator;
    TEST(!postingiterator.get_description().empty());
    copy_postingiterator = std::move(move_postingiterator);
    TEST(!copy_postingiterator.get_description().empty());

    Xapian::Query query;
    TEST(!query.get_description().empty());
    Xapian::Query copy_query(query);
    TEST(!copy_query.get_description().empty());
    Xapian::Query move_query(std::move(query));
    TEST(!move_query.get_description().empty());
    query = copy_query;
    TEST(!query.get_description().empty());
    copy_query = std::move(move_query);
    TEST(!copy_query.get_description().empty());

    Xapian::QueryParser queryparser;
    TEST(!queryparser.get_description().empty());
    Xapian::QueryParser copy_queryparser(queryparser);
    TEST(!copy_queryparser.get_description().empty());
    Xapian::QueryParser move_queryparser(std::move(queryparser));
    TEST(!move_queryparser.get_description().empty());
    queryparser = copy_queryparser;
    TEST(!queryparser.get_description().empty());
    copy_queryparser = std::move(move_queryparser);
    TEST(!copy_queryparser.get_description().empty());

    Xapian::RSet rset;
    TEST(!rset.get_description().empty());
    Xapian::RSet copy_rset(rset);
    TEST(!copy_rset.get_description().empty());
    Xapian::RSet move_rset(std::move(rset));
    TEST(!move_rset.get_description().empty());
    rset = copy_rset;
    TEST(!rset.get_description().empty());
    copy_rset = std::move(move_rset);
    TEST(!copy_rset.get_description().empty());

    Xapian::Registry registry;
    Xapian::Registry copy_registry(registry);
    Xapian::Registry move_registry(std::move(registry));
    registry = copy_registry;
    copy_registry = std::move(move_registry);

    Xapian::Stem stem;
    TEST(!stem.get_description().empty());
    Xapian::Stem copy_stem(stem);
    TEST(!copy_stem.get_description().empty());
    Xapian::Stem move_stem(std::move(stem));
    TEST(!move_stem.get_description().empty());
    stem = copy_stem;
    TEST(!stem.get_description().empty());
    copy_stem = std::move(move_stem);
    TEST(!copy_stem.get_description().empty());

    Xapian::TermGenerator termgenerator;
    TEST(!termgenerator.get_description().empty());
    Xapian::TermGenerator copy_termgenerator(termgenerator);
    TEST(!copy_termgenerator.get_description().empty());
    Xapian::TermGenerator move_termgenerator(std::move(termgenerator));
    TEST(!move_termgenerator.get_description().empty());
    termgenerator = copy_termgenerator;
    TEST(!termgenerator.get_description().empty());
    copy_termgenerator = std::move(move_termgenerator);
    TEST(!copy_termgenerator.get_description().empty());

    Xapian::TermIterator termiterator;
    TEST(!termiterator.get_description().empty());
    Xapian::TermIterator copy_termiterator(termiterator);
    TEST(!copy_termiterator.get_description().empty());
    Xapian::TermIterator move_termiterator(std::move(termiterator));
    TEST(!move_termiterator.get_description().empty());
    termiterator = copy_termiterator;
    TEST(!termiterator.get_description().empty());
    copy_termiterator = std::move(move_termiterator);
    TEST(!copy_termiterator.get_description().empty());

    Xapian::Utf8Iterator utf8iterator;
    Xapian::Utf8Iterator copy_utf8iterator(utf8iterator);
    Xapian::Utf8Iterator move_utf8iterator(std::move(utf8iterator));
    utf8iterator = copy_utf8iterator;
    copy_utf8iterator = std::move(move_utf8iterator);

    Xapian::ValueIterator valueiterator;
    TEST(!valueiterator.get_description().empty());
    Xapian::ValueIterator copy_valueiterator(valueiterator);
    TEST(!copy_valueiterator.get_description().empty());
    Xapian::ValueIterator move_valueiterator(std::move(valueiterator));
    TEST(!move_valueiterator.get_description().empty());
    valueiterator = copy_valueiterator;
    TEST(!valueiterator.get_description().empty());
    copy_valueiterator = std::move(move_valueiterator);
    TEST(!copy_valueiterator.get_description().empty());

    Xapian::WritableDatabase writabledatabase;
    TEST(!writabledatabase.get_description().empty());
    Xapian::WritableDatabase copy_writabledatabase(writabledatabase);
    TEST(!copy_writabledatabase.get_description().empty());
    Xapian::WritableDatabase move_writabledatabase(std::move(writabledatabase));
    TEST(!move_writabledatabase.get_description().empty());
    writabledatabase = copy_writabledatabase;
    TEST(!writabledatabase.get_description().empty());
    copy_writabledatabase = std::move(move_writabledatabase);
    TEST(!copy_writabledatabase.get_description().empty());

}

/// Test that iterator classes have consistent iterator traits.
DEFINE_TESTCASE(itortraits1, !backend) {
    {
        using traits = iterator_traits<Xapian::ESetIterator>;
        using pointer_base = std::remove_pointer<traits::pointer>::type;
        using reference_base = std::remove_reference<traits::reference>::type;
        static_assert(is_same<decltype(*std::declval<Xapian::ESetIterator>()),
                              pointer_base>::value,
                      "iterator_traits<ESetIterator>::pointer inconsistent with "
                      "type from dereferencing ESetIterator");
        static_assert(is_same<decltype(*std::declval<Xapian::ESetIterator>()),
                              reference_base>::value,
                      "iterator_traits<ESetIterator>::reference inconsistent with "
                      "type from dereferencing ESetIterator");
    }
    {
        using traits = iterator_traits<Xapian::MSetIterator>;
        using pointer_base = std::remove_pointer<traits::pointer>::type;
        using reference_base = std::remove_reference<traits::reference>::type;
        static_assert(is_same<decltype(*std::declval<Xapian::MSetIterator>()),
                              pointer_base>::value,
                      "iterator_traits<MSetIterator>::pointer inconsistent with "
                      "type from dereferencing MSetIterator");
        static_assert(is_same<decltype(*std::declval<Xapian::MSetIterator>()),
                              reference_base>::value,
                      "iterator_traits<MSetIterator>::reference inconsistent with "
                      "type from dereferencing MSetIterator");
    }
    {
        using traits = iterator_traits<Xapian::PositionIterator>;
        using pointer_base = std::remove_pointer<traits::pointer>::type;
        using reference_base = std::remove_reference<traits::reference>::type;
        static_assert(is_same<decltype(*std::declval<Xapian::PositionIterator>()),
                              pointer_base>::value,
                      "iterator_traits<PositionIterator>::pointer inconsistent with "
                      "type from dereferencing PositionIterator");
        static_assert(is_same<decltype(*std::declval<Xapian::PositionIterator>()),
                              reference_base>::value,
                      "iterator_traits<PositionIterator>::reference inconsistent with "
                      "type from dereferencing PositionIterator");
    }
    {
        using traits = iterator_traits<Xapian::PostingIterator>;
        using pointer_base = std::remove_pointer<traits::pointer>::type;
        using reference_base = std::remove_reference<traits::reference>::type;
        static_assert(is_same<decltype(*std::declval<Xapian::PostingIterator>()),
                              pointer_base>::value,
                      "iterator_traits<PostingIterator>::pointer inconsistent with "
                      "type from dereferencing PostingIterator");
        static_assert(is_same<decltype(*std::declval<Xapian::PostingIterator>()),
                              reference_base>::value,
                      "iterator_traits<PostingIterator>::reference inconsistent with "
                      "type from dereferencing PostingIterator");
    }
    {
        using traits = iterator_traits<Xapian::TermIterator>;
        using pointer_base = std::remove_pointer<traits::pointer>::type;
        using reference_base = std::remove_reference<traits::reference>::type;
        static_assert(is_same<decltype(*std::declval<Xapian::TermIterator>()),
                              pointer_base>::value,
                      "iterator_traits<TermIterator>::pointer inconsistent with "
                      "type from dereferencing TermIterator");
        static_assert(is_same<decltype(*std::declval<Xapian::TermIterator>()),
                              reference_base>::value,
                      "iterator_traits<TermIterator>::reference inconsistent with "
                      "type from dereferencing TermIterator");
    }
    {
        using traits = iterator_traits<Xapian::Utf8Iterator>;
        using pointer_base = std::remove_pointer<traits::pointer>::type;
        using reference_base = std::remove_reference<traits::reference>::type;
        static_assert(is_same<decltype(*std::declval<Xapian::Utf8Iterator>()),
                              pointer_base>::value,
                      "iterator_traits<Utf8Iterator>::pointer inconsistent with "
                      "type from dereferencing Utf8Iterator");
        static_assert(is_same<decltype(*std::declval<Xapian::Utf8Iterator>()),
                              reference_base>::value,
                      "iterator_traits<Utf8Iterator>::reference inconsistent with "
                      "type from dereferencing Utf8Iterator");
    }
    {
        using traits = iterator_traits<Xapian::ValueIterator>;
        using pointer_base = std::remove_pointer<traits::pointer>::type;
        using reference_base = std::remove_reference<traits::reference>::type;
        static_assert(is_same<decltype(*std::declval<Xapian::ValueIterator>()),
                              pointer_base>::value,
                      "iterator_traits<ValueIterator>::pointer inconsistent with "
                      "type from dereferencing ValueIterator");
        static_assert(is_same<decltype(*std::declval<Xapian::ValueIterator>()),
                              reference_base>::value,
                      "iterator_traits<ValueIterator>::reference inconsistent with "
                      "type from dereferencing ValueIterator");
    }
}

/// Test that container classes have consistent iterator traits.
DEFINE_TESTCASE(containertraits1, !backend) {
    {
        using pointer_base =
            std::remove_pointer<Xapian::ESet::pointer>::type;
        using reference_base =
            std::remove_reference<Xapian::ESet::reference>::type;
        using value_type = Xapian::ESet::value_type;
        static_assert(is_same<value_type, pointer_base>::value,
                      "Xapian::ESet::pointer inconsistent with "
                      "Xapian::ESet::value_type");
        static_assert(is_same<value_type, reference_base>::value,
                      "Xapian::ESet::reference inconsistent with "
                      "Xapian::ESet::value_type");
    }
    {
        using pointer_base =
            std::remove_pointer<Xapian::MSet::pointer>::type;
        using reference_base =
            std::remove_reference<Xapian::MSet::reference>::type;
        using value_type = Xapian::MSet::value_type;
        static_assert(is_same<value_type, pointer_base>::value,
                      "Xapian::MSet::pointer inconsistent with "
                      "Xapian::MSet::value_type");
        static_assert(is_same<value_type, reference_base>::value,
                      "Xapian::MSet::reference inconsistent with "
                      "Xapian::MSet::value_type");
    }
}
