<commit_before>/*************************************************
* SEED Source File                               *
* (C) 1999-2007 The Botan Project                *
*************************************************/

#include <botan/seed.h>
#include <botan/bit_ops.h>

namespace Botan {

/*************************************************
* SEED G Function                                *
*************************************************/
u32bit SEED::G_FUNC::operator()(u32bit X) const
   {
   return (S0[get_byte(3, X)] ^ S1[get_byte(2, X)] ^
           S2[get_byte(1, X)] ^ S3[get_byte(0, X)]);
   }

/*************************************************
* SEED Encryption                                *
*************************************************/
void SEED::enc(const byte in[], byte out[]) const
   {
   u32bit B0 = load_be<u32bit>(in, 0);
   u32bit B1 = load_be<u32bit>(in, 1);
   u32bit B2 = load_be<u32bit>(in, 2);
   u32bit B3 = load_be<u32bit>(in, 3);

   G_FUNC G;

   for(u32bit j = 0; j != 16; j += 2)
      {
      u32bit T0, T1;

      T0 = B2 ^ K[2*j];
      T1 = G(T0 ^ B3 ^ K[2*j+1]);
      T0 = G(T1 + T0);
      T1 = G(T1 + T0);
      B1 ^= T1;
      B0 ^= T0 + T1;

      T0 = B0 ^ K[2*j+2];
      T1 = G(T0 ^ B1 ^ K[2*j+3]);
      T0 = G(T1 + T0);
      T1 = G(T1 + T0);
      B3 ^= T1;
      B2 ^= T0 + T1;
      }

   store_be(out, B2, B3, B0, B1);
   }

/*************************************************
* SEED Decryption                                *
*************************************************/
void SEED::dec(const byte in[], byte out[]) const
   {
   u32bit B0 = load_be<u32bit>(in, 0);
   u32bit B1 = load_be<u32bit>(in, 1);
   u32bit B2 = load_be<u32bit>(in, 2);
   u32bit B3 = load_be<u32bit>(in, 3);

   G_FUNC G;

   for(u32bit j = 0; j != 16; j += 2)
      {
      u32bit T0, T1;

      T0 = B2 ^ K[30-2*j];
      T1 = G(T0 ^ B3 ^ K[31-2*j]);
      T0 = G(T1 + T0);
      T1 = G(T1 + T0);
      B1 ^= T1;
      B0 ^= T0 + T1;

      T0 = B0 ^ K[28-2*j];
      T1 = G(T0 ^ B1 ^ K[29-2*j]);
      T0 = G(T1 + T0);
      T1 = G(T1 + T0);
      B3 ^= T1;
      B2 ^= T0 + T1;
      }

   store_be(out, B2, B3, B0, B1);
   }

/*************************************************
* SEED Key Schedule                              *
*************************************************/
void SEED::key(const byte key[], u32bit)
   {
   const u32bit RC[16] = {
      0x9E3779B9, 0x3C6EF373, 0x78DDE6E6, 0xF1BBCDCC,
      0xE3779B99, 0xC6EF3733, 0x8DDE6E67, 0x1BBCDCCF,
      0x3779B99E, 0x6EF3733C, 0xDDE6E678, 0xBBCDCCF1,
      0x779B99E3, 0xEF3733C6, 0xDE6E678D, 0xBCDCCF1B
   };

   SecureBuffer<u32bit, 4> WK;

   for(u32bit j = 0; j != 4; ++j)
      WK[j] = load_be<u32bit>(key, j);

   G_FUNC G;

   for(u32bit j = 0; j != 16; j += 2)
      {
      K[2*j  ] = G(WK[0] + WK[2] - RC[j]);
      K[2*j+1] = G(WK[1] - WK[3] + RC[j]);

      byte T = get_byte(3, WK[0]);
      WK[0] = (WK[0] >> 8) | (get_byte(3, WK[1]) << 24);
      WK[1] = (WK[1] >> 8) | (T << 24);

      K[2*j+2] = G(WK[0] + WK[2] - RC[j+1]);
      K[2*j+3] = G(WK[1] - WK[3] + RC[j+1]);

      T = get_byte(0, WK[3]);
      WK[3] = (WK[3] << 8) | get_byte(0, WK[2]);
      WK[2] = (WK[2] << 8) | T;
      }
   }

}
<commit_msg>Fold an XOR operation that was happening during SEED encryption/decryption to occur inside the key schedule instead. This should lead to (slightly) better scheduling in the compiled code by reducing the length of a critical path.<commit_after>/*************************************************
* SEED Source File                               *
* (C) 1999-2007 The Botan Project                *
*************************************************/

#include <botan/seed.h>
#include <botan/bit_ops.h>

namespace Botan {

/*************************************************
* SEED G Function                                *
*************************************************/
u32bit SEED::G_FUNC::operator()(u32bit X) const
   {
   return (S0[get_byte(3, X)] ^ S1[get_byte(2, X)] ^
           S2[get_byte(1, X)] ^ S3[get_byte(0, X)]);
   }

/*************************************************
* SEED Encryption                                *
*************************************************/
void SEED::enc(const byte in[], byte out[]) const
   {
   u32bit B0 = load_be<u32bit>(in, 0);
   u32bit B1 = load_be<u32bit>(in, 1);
   u32bit B2 = load_be<u32bit>(in, 2);
   u32bit B3 = load_be<u32bit>(in, 3);

   G_FUNC G;

   for(u32bit j = 0; j != 16; j += 2)
      {
      u32bit T0, T1;

      T0 = B2 ^ K[2*j];
      T1 = G(B2 ^ B3 ^ K[2*j+1]);
      T0 = G(T1 + T0);
      T1 = G(T1 + T0);
      B1 ^= T1;
      B0 ^= T0 + T1;

      T0 = B0 ^ K[2*j+2];
      T1 = G(B0 ^ B1 ^ K[2*j+3]);
      T0 = G(T1 + T0);
      T1 = G(T1 + T0);
      B3 ^= T1;
      B2 ^= T0 + T1;
      }

   store_be(out, B2, B3, B0, B1);
   }

/*************************************************
* SEED Decryption                                *
*************************************************/
void SEED::dec(const byte in[], byte out[]) const
   {
   u32bit B0 = load_be<u32bit>(in, 0);
   u32bit B1 = load_be<u32bit>(in, 1);
   u32bit B2 = load_be<u32bit>(in, 2);
   u32bit B3 = load_be<u32bit>(in, 3);

   G_FUNC G;

   for(u32bit j = 0; j != 16; j += 2)
      {
      u32bit T0, T1;

      T0 = B2 ^ K[30-2*j];
      T1 = G(B2 ^ B3 ^ K[31-2*j]);
      T0 = G(T1 + T0);
      T1 = G(T1 + T0);
      B1 ^= T1;
      B0 ^= T0 + T1;

      T0 = B0 ^ K[28-2*j];
      T1 = G(B0 ^ B1 ^ K[29-2*j]);
      T0 = G(T1 + T0);
      T1 = G(T1 + T0);
      B3 ^= T1;
      B2 ^= T0 + T1;
      }

   store_be(out, B2, B3, B0, B1);
   }

/*************************************************
* SEED Key Schedule                              *
*************************************************/
void SEED::key(const byte key[], u32bit)
   {
   const u32bit RC[16] = {
      0x9E3779B9, 0x3C6EF373, 0x78DDE6E6, 0xF1BBCDCC,
      0xE3779B99, 0xC6EF3733, 0x8DDE6E67, 0x1BBCDCCF,
      0x3779B99E, 0x6EF3733C, 0xDDE6E678, 0xBBCDCCF1,
      0x779B99E3, 0xEF3733C6, 0xDE6E678D, 0xBCDCCF1B
   };

   SecureBuffer<u32bit, 4> WK;

   for(u32bit j = 0; j != 4; ++j)
      WK[j] = load_be<u32bit>(key, j);

   G_FUNC G;

   for(u32bit j = 0; j != 16; j += 2)
      {
      K[2*j  ] = G(WK[0] + WK[2] - RC[j]);
      K[2*j+1] = G(WK[1] - WK[3] + RC[j]) ^ K[2*j];

      byte T = get_byte(3, WK[0]);
      WK[0] = (WK[0] >> 8) | (get_byte(3, WK[1]) << 24);
      WK[1] = (WK[1] >> 8) | (T << 24);

      K[2*j+2] = G(WK[0] + WK[2] - RC[j+1]);
      K[2*j+3] = G(WK[1] - WK[3] + RC[j+1]) ^ K[2*j+2];

      T = get_byte(0, WK[3]);
      WK[3] = (WK[3] << 8) | get_byte(0, WK[2]);
      WK[2] = (WK[2] << 8) | T;
      }
   }

}
<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkException.h"

void mitk::Exception::AddRethrowData(const char *file, unsigned int lineNumber, const char *message)
    {
    mitk::Exception::ReThrowData data = {file, lineNumber, message};
    this->m_RethrowData.push_back(data);
    }

int mitk::Exception::GetNumberOfRethrows()
    {
    return (int)m_RethrowData.size();
    }

void mitk::Exception::GetRethrowData(int rethrowNumber, std::string &file, int &line, std::string &message)
    {
      if ((rethrowNumber >= (int)m_RethrowData.size()) || (rethrowNumber<0))
        {
        file = "";
        line = 0;
        message = "";
        return;
        }

    file = m_RethrowData.at(rethrowNumber).RethrowClassname;
    line = m_RethrowData.at(rethrowNumber).RethrowLine;
    message = m_RethrowData.at(rethrowNumber).RethrowMessage;
}

std::ostream& operator<<(std::ostream& os, const mitk::Exception& e)
{
  os << e.GetDescription();
  return os;
}
<commit_msg>COMP: Fixed namespace of operator<< implementation<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkException.h"

void mitk::Exception::AddRethrowData(const char *file, unsigned int lineNumber, const char *message)
    {
    mitk::Exception::ReThrowData data = {file, lineNumber, message};
    this->m_RethrowData.push_back(data);
    }

int mitk::Exception::GetNumberOfRethrows()
    {
    return (int)m_RethrowData.size();
    }

void mitk::Exception::GetRethrowData(int rethrowNumber, std::string &file, int &line, std::string &message)
    {
      if ((rethrowNumber >= (int)m_RethrowData.size()) || (rethrowNumber<0))
        {
        file = "";
        line = 0;
        message = "";
        return;
        }

    file = m_RethrowData.at(rethrowNumber).RethrowClassname;
    line = m_RethrowData.at(rethrowNumber).RethrowLine;
    message = m_RethrowData.at(rethrowNumber).RethrowMessage;
}

std::ostream& mitk::operator<<(std::ostream& os, const mitk::Exception& e)
{
  os << e.GetDescription();
  return os;
}
<|endoftext|>


<commit_before>/*
    This file is part of Akregator.

    Copyright (C) 2008 Frank Osterfeld <osterfeld@kde.org>

    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, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "createfeedcommand.h"

#include "addfeeddialog.h"
#include "feed.h"
#include "feedpropertiesdialog.h"
#include "folder.h"
#include "subscriptionlistview.h"

#include <KInputDialog>
#include <KLocalizedString>
#include <KUrl>

#include <QPointer>
#include <QTimer>
#include <QClipboard>

#include <cassert>

using namespace Akregator;

class CreateFeedCommand::Private
{
    CreateFeedCommand* const q;
public:
    explicit Private( CreateFeedCommand* qq );

    void doCreate();

    QPointer<Folder> m_rootFolder;
    QPointer<SubscriptionListView> m_subscriptionListView;
    QString m_url;
    QPointer<Folder> m_parentFolder;
    QPointer<TreeNode> m_after;
    bool m_autoexec;
};

CreateFeedCommand::Private::Private( CreateFeedCommand* qq )
  : q( qq ),
    m_rootFolder( 0 ),
    m_subscriptionListView( 0 ),
    m_parentFolder( 0 ),
    m_after( 0 ),
    m_autoexec( false )
{

}

void CreateFeedCommand::Private::doCreate()
{
    assert( m_rootFolder );
    assert( m_subscriptionListView );

    QPointer<AddFeedDialog> afd = new AddFeedDialog( q->parentWidget(), "add_feed" );

    QString url = m_url;

    if( url.isEmpty() )
    {
        const QClipboard* const clipboard = QApplication::clipboard();
        assert( clipboard );
        const QString clipboardText = clipboard->text();
        // Check for the hostname, since the isValid method is not strict enough
        if( !KUrl( clipboardText ).isEmpty() )
            url = clipboardText;
    }

    afd->setUrl( KUrl::fromPercentEncoding( url.toLatin1() ) );

    QPointer<QObject> thisPointer( q );

    if ( m_autoexec )
        afd->accept();
    else
        afd->exec();

    if ( !thisPointer ) // "this" might have been deleted while exec()!
        return;

    Feed* const feed = afd->feed();
    delete afd;

    if ( !feed )
    {
        q->done();
        return;
    }

    QPointer<FeedPropertiesDialog> dlg = new FeedPropertiesDialog( q->parentWidget(), "edit_feed" );
    dlg->setFeed( feed );
    dlg->selectFeedName();

    if ( !m_autoexec && ( dlg->exec() != QDialog::Accepted || !thisPointer ) )
    {
        delete feed;
    }
    else
    {
        m_parentFolder = m_parentFolder ? m_parentFolder : m_rootFolder;
        m_parentFolder->insertChild( feed, m_after );
        m_subscriptionListView->ensureNodeVisible( feed );
    }

    delete dlg;
    q->done();
}

CreateFeedCommand::CreateFeedCommand( QObject* parent ) : Command( parent ), d( new Private( this ) )
{

}

CreateFeedCommand::~CreateFeedCommand()
{
    delete d;
}

void CreateFeedCommand::setSubscriptionListView( SubscriptionListView* view )
{
    d->m_subscriptionListView = view;
}

void CreateFeedCommand::setRootFolder( Folder* rootFolder )
{
    d->m_rootFolder = rootFolder;
}

void CreateFeedCommand::setUrl( const QString& url )
{
    d->m_url = url;
}

void CreateFeedCommand::setPosition( Folder* parent, TreeNode* after )
{
    d->m_parentFolder = parent;
    d->m_after = after;
}

void CreateFeedCommand::setAutoExecute( bool autoexec )
{
    d->m_autoexec = autoexec;
}

void CreateFeedCommand::doStart()
{
    QTimer::singleShot( 0, this, SLOT( doCreate() ) );
}

void CreateFeedCommand::doAbort()
{

}

#include "createfeedcommand.moc"
<commit_msg>actually do what the comment says: check host() for being empty, not the whole URL prevents non-URL clipboard content from being pasted<commit_after>/*
    This file is part of Akregator.

    Copyright (C) 2008 Frank Osterfeld <osterfeld@kde.org>

    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, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "createfeedcommand.h"

#include "addfeeddialog.h"
#include "feed.h"
#include "feedpropertiesdialog.h"
#include "folder.h"
#include "subscriptionlistview.h"

#include <KInputDialog>
#include <KLocalizedString>
#include <KUrl>

#include <QPointer>
#include <QTimer>
#include <QClipboard>

#include <cassert>

using namespace Akregator;

class CreateFeedCommand::Private
{
    CreateFeedCommand* const q;
public:
    explicit Private( CreateFeedCommand* qq );

    void doCreate();

    QPointer<Folder> m_rootFolder;
    QPointer<SubscriptionListView> m_subscriptionListView;
    QString m_url;
    QPointer<Folder> m_parentFolder;
    QPointer<TreeNode> m_after;
    bool m_autoexec;
};

CreateFeedCommand::Private::Private( CreateFeedCommand* qq )
  : q( qq ),
    m_rootFolder( 0 ),
    m_subscriptionListView( 0 ),
    m_parentFolder( 0 ),
    m_after( 0 ),
    m_autoexec( false )
{

}

void CreateFeedCommand::Private::doCreate()
{
    assert( m_rootFolder );
    assert( m_subscriptionListView );

    QPointer<AddFeedDialog> afd = new AddFeedDialog( q->parentWidget(), "add_feed" );

    QString url = m_url;

    if( url.isEmpty() )
    {
        const QClipboard* const clipboard = QApplication::clipboard();
        assert( clipboard );
        const QString clipboardText = clipboard->text();
        // Check for the hostname, since the isValid method is not strict enough
        if( !KUrl( clipboardText ).host().isEmpty() )
            url = clipboardText;
    }

    afd->setUrl( KUrl::fromPercentEncoding( url.toLatin1() ) );

    QPointer<QObject> thisPointer( q );

    if ( m_autoexec )
        afd->accept();
    else
        afd->exec();

    if ( !thisPointer ) // "this" might have been deleted while exec()!
        return;

    Feed* const feed = afd->feed();
    delete afd;

    if ( !feed )
    {
        q->done();
        return;
    }

    QPointer<FeedPropertiesDialog> dlg = new FeedPropertiesDialog( q->parentWidget(), "edit_feed" );
    dlg->setFeed( feed );
    dlg->selectFeedName();

    if ( !m_autoexec && ( dlg->exec() != QDialog::Accepted || !thisPointer ) )
    {
        delete feed;
    }
    else
    {
        m_parentFolder = m_parentFolder ? m_parentFolder : m_rootFolder;
        m_parentFolder->insertChild( feed, m_after );
        m_subscriptionListView->ensureNodeVisible( feed );
    }

    delete dlg;
    q->done();
}

CreateFeedCommand::CreateFeedCommand( QObject* parent ) : Command( parent ), d( new Private( this ) )
{

}

CreateFeedCommand::~CreateFeedCommand()
{
    delete d;
}

void CreateFeedCommand::setSubscriptionListView( SubscriptionListView* view )
{
    d->m_subscriptionListView = view;
}

void CreateFeedCommand::setRootFolder( Folder* rootFolder )
{
    d->m_rootFolder = rootFolder;
}

void CreateFeedCommand::setUrl( const QString& url )
{
    d->m_url = url;
}

void CreateFeedCommand::setPosition( Folder* parent, TreeNode* after )
{
    d->m_parentFolder = parent;
    d->m_after = after;
}

void CreateFeedCommand::setAutoExecute( bool autoexec )
{
    d->m_autoexec = autoexec;
}

void CreateFeedCommand::doStart()
{
    QTimer::singleShot( 0, this, SLOT( doCreate() ) );
}

void CreateFeedCommand::doAbort()
{

}

#include "createfeedcommand.moc"
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */
//  TEST    Foundation::Containers::DataStructures::DoublyLinkedList
#include "Stroika/Foundation/StroikaPreComp.h"

#include <iostream>
#include <sstream>

#include "Stroika/Foundation/Containers/Private/PatchingDataStructures/DoublyLinkedList.h"

#include "Stroika/Foundation/Debug/Assertions.h"
#include "Stroika/Foundation/Debug/Trace.h"

#include "../TestHarness/SimpleClass.h"
#include "../TestHarness/TestHarness.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::Containers::DataStructures;
using namespace Stroika::Foundation::Containers::Private::PatchingDataStructures;

using Traversal::kUnknownIteratorOwnerID;

namespace {
    static void Test1 ()
    {
        Private::PatchingDataStructures::DoublyLinkedList<size_t> someLL;
        const size_t                                              kBigSize = 1001;

        Assert (kBigSize > 100);
        VerifyTestResult (someLL.GetLength () == 0);
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }
        someLL.RemoveAll ();
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }
        {
            for (size_t i = 1; i <= kBigSize - 10; i++) {
                someLL.RemoveFirst ();
            }
        }
        someLL.RemoveAll (); //  someLL.SetLength(kBigSize, 0);
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }

        VerifyTestResult (someLL.GetLength () == kBigSize);
        someLL.SetAt (55, 55);                      //  someLL [55] = 55;
        VerifyTestResult (someLL.GetAt (55) == 55); //  VerifyTestResult(someArray [55] == 55);
        VerifyTestResult (someLL.GetAt (55) != 56); //  VerifyTestResult(someArray [55] != 56);
        {
            size_t i = 1;
            size_t cur;
            for (Private::PatchingDataStructures::DoublyLinkedList<size_t>::ForwardIterator it (kUnknownIteratorOwnerID, &someLL); it.More (&cur, true); i++) {
                if (i == 100) {
                    someLL.AddAfter (it, 1);
                    break;
                }
            }
        } //   someLL.InsertAt(1, 100);

        VerifyTestResult (someLL.GetLength () == kBigSize + 1);
        VerifyTestResult (someLL.GetAt (100) == 1); //  VerifyTestResult(someArray [100] == 1);

        someLL.SetAt (101, someLL.GetAt (100) + 5);

        VerifyTestResult (someLL.GetAt (101) == 6);
        someLL.RemoveFirst ();
        VerifyTestResult (someLL.GetAt (100) == 6);
    }

    static void Test2 ()
    {
        Private::PatchingDataStructures::DoublyLinkedList<SimpleClass> someLL;
        const size_t                                                   kBigSize = 1000;

        VerifyTestResult (someLL.GetLength () == 0);

        Assert (kBigSize > 10);
        VerifyTestResult (someLL.GetLength () == 0);
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }
        someLL.RemoveAll ();
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }
        {
            for (size_t i = 1; i <= kBigSize - 10; i++) {
                someLL.RemoveFirst ();
            }
        }
        someLL.RemoveAll (); //  someLL.SetLength(kBigSize, 0);
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }

        VerifyTestResult (someLL.GetLength () == kBigSize);

        someLL.SetAt (55, 55); //  someLL [55] = 55;
        VerifyTestResult (someLL.GetAt (55) == 55);
        VerifyTestResult (not(someLL.GetAt (55) == 56));

        someLL.RemoveAll ();
        VerifyTestResult (someLL.GetLength () == 0);

        for (size_t i = kBigSize; i >= 1; --i) {
            VerifyTestResult (not someLL.Contains (i));
            someLL.Prepend (i);
            VerifyTestResult (someLL.GetFirst () == i);
            VerifyTestResult (someLL.Contains (i));
        }
        for (size_t i = 1; i <= kBigSize; ++i) {
            VerifyTestResult (someLL.GetFirst () == i);
            someLL.RemoveFirst ();
            VerifyTestResult (not someLL.Contains (i));
        }
        VerifyTestResult (someLL.GetLength () == 0);

        for (size_t i = kBigSize; i >= 1; --i) {
            someLL.Prepend (i);
        }
        for (size_t i = kBigSize; i >= 1; --i) {
            //cerr << "i, getat(i-1) = " << i << ", " << someLL.GetAt (i-1).GetValue () << endl;
            VerifyTestResult (someLL.GetAt (i - 1) == i);
        }
    }
}

namespace {

    void DoRegressionTests_ ()
    {
        Test1 ();
        Test2 ();
    }
}

int main ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
{
    Stroika::TestHarness::Setup ();
    return Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
}
<commit_msg>fixed remiaing refernece to  Private::PatchingDataStructures<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */
//  TEST    Foundation::Containers::DataStructures::DoublyLinkedList
#include "Stroika/Foundation/StroikaPreComp.h"

#include <iostream>
#include <sstream>

#include "Stroika/Foundation/Containers/DataStructures/DoublyLinkedList.h"

#include "Stroika/Foundation/Debug/Assertions.h"
#include "Stroika/Foundation/Debug/Trace.h"

#include "../TestHarness/SimpleClass.h"
#include "../TestHarness/TestHarness.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::Containers::DataStructures;

using Traversal::kUnknownIteratorOwnerID;

namespace {
    static void Test1 ()
    {
        DataStructures::DoublyLinkedList<size_t> someLL;
        const size_t                                              kBigSize = 1001;

        Assert (kBigSize > 100);
        VerifyTestResult (someLL.GetLength () == 0);
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }
        someLL.RemoveAll ();
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }
        {
            for (size_t i = 1; i <= kBigSize - 10; i++) {
                someLL.RemoveFirst ();
            }
        }
        someLL.RemoveAll (); //  someLL.SetLength(kBigSize, 0);
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }

        VerifyTestResult (someLL.GetLength () == kBigSize);
        someLL.SetAt (55, 55);                      //  someLL [55] = 55;
        VerifyTestResult (someLL.GetAt (55) == 55); //  VerifyTestResult(someArray [55] == 55);
        VerifyTestResult (someLL.GetAt (55) != 56); //  VerifyTestResult(someArray [55] != 56);
        {
            size_t i = 1;
            size_t cur;
            for (DataStructures::DoublyLinkedList<size_t>::ForwardIterator it (&someLL); it.More (&cur, true); i++) {
                if (i == 100) {
                    someLL.AddAfter (it, 1);
                    break;
                }
            }
        } //   someLL.InsertAt(1, 100);

        VerifyTestResult (someLL.GetLength () == kBigSize + 1);
        VerifyTestResult (someLL.GetAt (100) == 1); //  VerifyTestResult(someArray [100] == 1);

        someLL.SetAt (101, someLL.GetAt (100) + 5);

        VerifyTestResult (someLL.GetAt (101) == 6);
        someLL.RemoveFirst ();
        VerifyTestResult (someLL.GetAt (100) == 6);
    }

    static void Test2 ()
    {
        DataStructures::DoublyLinkedList<SimpleClass> someLL;
        const size_t                                                   kBigSize = 1000;

        VerifyTestResult (someLL.GetLength () == 0);

        Assert (kBigSize > 10);
        VerifyTestResult (someLL.GetLength () == 0);
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }
        someLL.RemoveAll ();
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }
        {
            for (size_t i = 1; i <= kBigSize - 10; i++) {
                someLL.RemoveFirst ();
            }
        }
        someLL.RemoveAll (); //  someLL.SetLength(kBigSize, 0);
        {
            for (size_t i = 1; i <= kBigSize; i++) {
                someLL.Prepend (0);
            }
        }

        VerifyTestResult (someLL.GetLength () == kBigSize);

        someLL.SetAt (55, 55); //  someLL [55] = 55;
        VerifyTestResult (someLL.GetAt (55) == 55);
        VerifyTestResult (not(someLL.GetAt (55) == 56));

        someLL.RemoveAll ();
        VerifyTestResult (someLL.GetLength () == 0);

        for (size_t i = kBigSize; i >= 1; --i) {
            VerifyTestResult (not someLL.Contains (i));
            someLL.Prepend (i);
            VerifyTestResult (someLL.GetFirst () == i);
            VerifyTestResult (someLL.Contains (i));
        }
        for (size_t i = 1; i <= kBigSize; ++i) {
            VerifyTestResult (someLL.GetFirst () == i);
            someLL.RemoveFirst ();
            VerifyTestResult (not someLL.Contains (i));
        }
        VerifyTestResult (someLL.GetLength () == 0);

        for (size_t i = kBigSize; i >= 1; --i) {
            someLL.Prepend (i);
        }
        for (size_t i = kBigSize; i >= 1; --i) {
            //cerr << "i, getat(i-1) = " << i << ", " << someLL.GetAt (i-1).GetValue () << endl;
            VerifyTestResult (someLL.GetAt (i - 1) == i);
        }
    }
}

namespace {

    void DoRegressionTests_ ()
    {
        Test1 ();
        Test2 ();
    }
}

int main ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
{
    Stroika::TestHarness::Setup ();
    return Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2022.  All rights reserved
 */
//  TEST    Foundation::Execution::Other
#include "Stroika/Foundation/StroikaPreComp.h"

#include "Stroika/Foundation/Common/Property.h"
#include "Stroika/Foundation/DataExchange/ObjectVariantMapper.h"
#include "Stroika/Foundation/DataExchange/OptionsFile.h"
#include "Stroika/Foundation/Debug/Assertions.h"
#include "Stroika/Foundation/Debug/Trace.h"
#include "Stroika/Foundation/Execution/CommandLine.h"
#include "Stroika/Foundation/Execution/Finally.h"
#include "Stroika/Foundation/Execution/Function.h"
#include "Stroika/Foundation/Execution/Logger.h"
#include "Stroika/Foundation/Execution/ModuleGetterSetter.h"
#include "Stroika/Foundation/Time/DateTime.h"
#include "Stroika/Foundation/Time/Duration.h"

#include "../TestHarness/SimpleClass.h"
#include "../TestHarness/TestHarness.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Characters;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::Execution;

// must be tested before main, so cannot call directly below
namespace {
    int        TestAtomicInitializedCoorectly_ ();
    static int sIgnoredTestValue_ = TestAtomicInitializedCoorectly_ (); // if using static constructors, this will be called before sAtomicBoolNotInitializedTilAfterStaticInitizers_

    atomic<bool> sAtomicBoolNotInitializedTilAfterStaticInitizers_{true}; // for calls before start of or after end of main ()
    int          TestAtomicInitializedCoorectly_ ()
    {
#if qCompilerAndStdLib_atomic_bool_initialize_before_main_Buggy
        if (sAtomicBoolNotInitializedTilAfterStaticInitizers_) {
#if qDebug
            // bug seems to happen just with DEBUG builds - haven't dug into why
            Stroika::TestHarness::WarnTestIssue ("qCompilerAndStdLib_atomic_bool_initialize_before_main_Buggy MAYBE fixed");
#endif
        }
#else
        VerifyTestResult (sAtomicBoolNotInitializedTilAfterStaticInitizers_);
#endif
        return 1;
    }
}

namespace {
    void Test1_Function_ ()
    {
        // Make sure Function<> works as well as std::function
        {
            Function<int (bool)> f = [] ([[maybe_unused]] bool b) -> int { return 3; };
            VerifyTestResult (f (true) == 3);
            function<int (bool)> ff = f;
            VerifyTestResult (ff (true) == 3);
        }
        // Make sure Function<> serves its one purpose - being comparable
        {
            Function<int (bool)> f1 = [] ([[maybe_unused]] bool b) -> int { return 3; };
            Function<int (bool)> f2 = [] ([[maybe_unused]] bool b) -> int { return 3; };

            VerifyTestResult (f1 != f2);
            VerifyTestResult (f1 < f2 or f2 < f1);
            Function<int (bool)> f3 = f1;
            VerifyTestResult (f3 == f1);
            VerifyTestResult (f3 != f2);
        }
    }
}

namespace {
    void Test2_CommandLine_ ()
    {
        {
            String           cmdLine = L"/bin/sh -c \"a b c\"";
            Sequence<String> l       = ParseCommandLine (cmdLine);
            VerifyTestResult (l.size () == 3);
            VerifyTestResult (l[0] == L"/bin/sh");
            VerifyTestResult (l[1] == L"-c");
            VerifyTestResult (l[2] == L"a b c");
        }
        {
            String           cmdLine = L"";
            Sequence<String> l       = ParseCommandLine (cmdLine);
            VerifyTestResult (l.size () == 0);
        }
        {
            String           cmdLine = L"/bin/sh -c \'a b c\'";
            Sequence<String> l       = ParseCommandLine (cmdLine);
            VerifyTestResult (l.size () == 3);
            VerifyTestResult (l[0] == L"/bin/sh");
            VerifyTestResult (l[1] == L"-c");
            VerifyTestResult (l[2] == L"a b c");
        }
        {
            String           cmdLine = L"/bin/sh\t b c     -d";
            Sequence<String> l       = ParseCommandLine (cmdLine);
            VerifyTestResult (l.size () == 4);
            VerifyTestResult (l[0] == L"/bin/sh");
            VerifyTestResult (l[1] == L"b");
            VerifyTestResult (l[2] == L"c");
            VerifyTestResult (l[3] == L"-d");
        }
    }
}

namespace {
    namespace Test3_ {
        void DoAll ()
        {
            {
                unsigned int cnt = 0;
                {
                    [[maybe_unused]] auto&& c = Finally (
                        [&cnt] () noexcept {
                            cnt--;
                        });
                    ++cnt;
                }
                VerifyTestResult (cnt == 0);
            }
        }
    }
}

namespace {
    namespace Test4_ConstantProperty_ {
        namespace Private_ {
            namespace T1_ {
                static const String                    x{L"3"};
                const Common::ConstantProperty<String> kX = [] () { return x; };
                void                                   DoIt ()
                {
                    const String a = kX;
                }
            }
            namespace T2_ {
                const Common::ConstantProperty<String> kX = [] () { return L"6"; };
                void                                   DoIt ()
                {
                    const String a = kX;
                    VerifyTestResult (a == L"6"); // Before Stroika 2.1b12 there was a bug that ConstantProperty stored teh constant in a static variable not data member!
                }
            }
            namespace T3_ {
                // @todo get constexpr working - see docs for Common::ConstantProperty
                //constexpr Common::ConstantProperty<int> kX = [] () { return 3; };
                const Common::ConstantProperty<int> kX = [] () { return 3; };
                void                                DoIt ()
                {
                    const int a [[maybe_unused]] = kX;
                }
            }
            namespace T4_ {
                const Common::ConstantProperty<int> kX = [] () { return 4; };
                void                                DoIt ()
                {
                    const int a [[maybe_unused]] = kX;
                    VerifyTestResult (a == 4); // Before Stroika 2.1b12 there was a bug that ConstantProperty stored teh constant in a static variable not data member!
                }
            }
        }
        void DoAll ()
        {
            Private_::T1_::DoIt ();
            Private_::T2_::DoIt ();
            Private_::T3_::DoIt ();
        }
    }
}

namespace {
    namespace Test5_ModuleGetterSetter_ {
        namespace PRIVATE_ {
            using namespace DataExchange;
            using namespace Execution;
            using namespace Time;
            static const Duration kMinTime_ = 1s;
            struct MyData_ {
                bool               fEnabled = false;
                optional<DateTime> fLastSynchronizedAt;
            };
            struct ModuleGetterSetter_Implementation_MyData_ {
                ModuleGetterSetter_Implementation_MyData_ ()
                    : fOptionsFile_{
                          L"MyModule",
                          [] () -> ObjectVariantMapper {
                              ObjectVariantMapper mapper;
                              mapper.AddClass<MyData_> (initializer_list<ObjectVariantMapper::StructFieldInfo>{
                                  {L"Enabled", StructFieldMetaInfo{&MyData_::fEnabled}},
                                  {L"Last-Synchronized-At", StructFieldMetaInfo{&MyData_::fLastSynchronizedAt}},
                              });
                              return mapper;
                          }(),
                          OptionsFile::kDefaultUpgrader, OptionsFile::mkFilenameMapper (L"Put-Your-App-Name-Here")}
                    , fActualCurrentConfigData_{fOptionsFile_.Read<MyData_> (MyData_{})}
                {
                    Set (fActualCurrentConfigData_); // assure derived data (and changed fields etc) up to date
                }
                MyData_ Get () const
                {
                    return fActualCurrentConfigData_;
                }
                void Set (const MyData_& v)
                {
                    fActualCurrentConfigData_ = v;
                    fOptionsFile_.Write (v);
                }

            private:
                OptionsFile fOptionsFile_;
                MyData_     fActualCurrentConfigData_; // automatically initialized just in time, and externally synchronized
            };

            using Execution::ModuleGetterSetter;
            ModuleGetterSetter<MyData_, ModuleGetterSetter_Implementation_MyData_> sModuleConfiguration_;

            void TestUse1_ ()
            {
                if (sModuleConfiguration_.Get ().fEnabled) {
                    auto n     = sModuleConfiguration_.Get ();
                    n.fEnabled = false;
                    sModuleConfiguration_.Set (n);
                }
            }
            void TestUse2_ ()
            {
                sModuleConfiguration_.Update ([] (MyData_ data) { MyData_ result = data; if (result.fLastSynchronizedAt.has_value () and *result.fLastSynchronizedAt + kMinTime_ > DateTime::Now ()) { result.fLastSynchronizedAt = DateTime::Now (); } return result; });
            }
            void TestUse3_ ()
            {
                if (sModuleConfiguration_.Update ([] (const MyData_& data) -> optional<MyData_> {  if (data.fLastSynchronizedAt.has_value () and *data.fLastSynchronizedAt + kMinTime_ > DateTime::Now ()) { MyData_ result = data; result.fLastSynchronizedAt = DateTime::Now (); return result; } return {}; })) {
                    // e.g. trigger someone to wakeup and used changes?
                }
            }
        }
        void DoAll ()
        {
            PRIVATE_::TestUse1_ ();
            PRIVATE_::TestUse2_ ();
            PRIVATE_::TestUse3_ ();
        }
    }
}

namespace {
    void DoRegressionTests_ ()
    {
        Execution::Logger::Activator logMgrActivator;   // needed for OptionsFile test
        Test1_Function_ ();
        Test2_CommandLine_ ();
        Test3_::DoAll ();
        Test4_ConstantProperty_::DoAll ();
        Test5_ModuleGetterSetter_::DoAll ();
    }
}

int main ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
{
    Stroika::TestHarness::Setup ();
    return Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
}
<commit_msg>cosmetic<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2022.  All rights reserved
 */
//  TEST    Foundation::Execution::Other
#include "Stroika/Foundation/StroikaPreComp.h"

#include "Stroika/Foundation/Common/Property.h"
#include "Stroika/Foundation/DataExchange/ObjectVariantMapper.h"
#include "Stroika/Foundation/DataExchange/OptionsFile.h"
#include "Stroika/Foundation/Debug/Assertions.h"
#include "Stroika/Foundation/Debug/Trace.h"
#include "Stroika/Foundation/Execution/CommandLine.h"
#include "Stroika/Foundation/Execution/Finally.h"
#include "Stroika/Foundation/Execution/Function.h"
#include "Stroika/Foundation/Execution/Logger.h"
#include "Stroika/Foundation/Execution/ModuleGetterSetter.h"
#include "Stroika/Foundation/Time/DateTime.h"
#include "Stroika/Foundation/Time/Duration.h"

#include "../TestHarness/SimpleClass.h"
#include "../TestHarness/TestHarness.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Characters;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::Execution;

// must be tested before main, so cannot call directly below
namespace {
    int        TestAtomicInitializedCoorectly_ ();
    static int sIgnoredTestValue_ = TestAtomicInitializedCoorectly_ (); // if using static constructors, this will be called before sAtomicBoolNotInitializedTilAfterStaticInitizers_

    atomic<bool> sAtomicBoolNotInitializedTilAfterStaticInitizers_{true}; // for calls before start of or after end of main ()
    int          TestAtomicInitializedCoorectly_ ()
    {
#if qCompilerAndStdLib_atomic_bool_initialize_before_main_Buggy
        if (sAtomicBoolNotInitializedTilAfterStaticInitizers_) {
#if qDebug
            // bug seems to happen just with DEBUG builds - haven't dug into why
            Stroika::TestHarness::WarnTestIssue ("qCompilerAndStdLib_atomic_bool_initialize_before_main_Buggy MAYBE fixed");
#endif
        }
#else
        VerifyTestResult (sAtomicBoolNotInitializedTilAfterStaticInitizers_);
#endif
        return 1;
    }
}

namespace {
    void Test1_Function_ ()
    {
        // Make sure Function<> works as well as std::function
        {
            Function<int (bool)> f = [] ([[maybe_unused]] bool b) -> int { return 3; };
            VerifyTestResult (f (true) == 3);
            function<int (bool)> ff = f;
            VerifyTestResult (ff (true) == 3);
        }
        // Make sure Function<> serves its one purpose - being comparable
        {
            Function<int (bool)> f1 = [] ([[maybe_unused]] bool b) -> int { return 3; };
            Function<int (bool)> f2 = [] ([[maybe_unused]] bool b) -> int { return 3; };

            VerifyTestResult (f1 != f2);
            VerifyTestResult (f1 < f2 or f2 < f1);
            Function<int (bool)> f3 = f1;
            VerifyTestResult (f3 == f1);
            VerifyTestResult (f3 != f2);
        }
    }
}

namespace {
    void Test2_CommandLine_ ()
    {
        {
            String           cmdLine = L"/bin/sh -c \"a b c\"";
            Sequence<String> l       = ParseCommandLine (cmdLine);
            VerifyTestResult (l.size () == 3);
            VerifyTestResult (l[0] == L"/bin/sh");
            VerifyTestResult (l[1] == L"-c");
            VerifyTestResult (l[2] == L"a b c");
        }
        {
            String           cmdLine = L"";
            Sequence<String> l       = ParseCommandLine (cmdLine);
            VerifyTestResult (l.size () == 0);
        }
        {
            String           cmdLine = L"/bin/sh -c \'a b c\'";
            Sequence<String> l       = ParseCommandLine (cmdLine);
            VerifyTestResult (l.size () == 3);
            VerifyTestResult (l[0] == L"/bin/sh");
            VerifyTestResult (l[1] == L"-c");
            VerifyTestResult (l[2] == L"a b c");
        }
        {
            String           cmdLine = L"/bin/sh\t b c     -d";
            Sequence<String> l       = ParseCommandLine (cmdLine);
            VerifyTestResult (l.size () == 4);
            VerifyTestResult (l[0] == L"/bin/sh");
            VerifyTestResult (l[1] == L"b");
            VerifyTestResult (l[2] == L"c");
            VerifyTestResult (l[3] == L"-d");
        }
    }
}

namespace {
    namespace Test3_ {
        void DoAll ()
        {
            {
                unsigned int cnt = 0;
                {
                    [[maybe_unused]] auto&& c = Finally (
                        [&cnt] () noexcept {
                            cnt--;
                        });
                    ++cnt;
                }
                VerifyTestResult (cnt == 0);
            }
        }
    }
}

namespace {
    namespace Test4_ConstantProperty_ {
        namespace Private_ {
            namespace T1_ {
                static const String                    x{L"3"};
                const Common::ConstantProperty<String> kX = [] () { return x; };
                void                                   DoIt ()
                {
                    const String a = kX;
                }
            }
            namespace T2_ {
                const Common::ConstantProperty<String> kX = [] () { return L"6"; };
                void                                   DoIt ()
                {
                    const String a = kX;
                    VerifyTestResult (a == L"6"); // Before Stroika 2.1b12 there was a bug that ConstantProperty stored teh constant in a static variable not data member!
                }
            }
            namespace T3_ {
                // @todo get constexpr working - see docs for Common::ConstantProperty
                //constexpr Common::ConstantProperty<int> kX = [] () { return 3; };
                const Common::ConstantProperty<int> kX = [] () { return 3; };
                void                                DoIt ()
                {
                    const int a [[maybe_unused]] = kX;
                }
            }
            namespace T4_ {
                const Common::ConstantProperty<int> kX = [] () { return 4; };
                void                                DoIt ()
                {
                    const int a [[maybe_unused]] = kX;
                    VerifyTestResult (a == 4); // Before Stroika 2.1b12 there was a bug that ConstantProperty stored teh constant in a static variable not data member!
                }
            }
        }
        void DoAll ()
        {
            Private_::T1_::DoIt ();
            Private_::T2_::DoIt ();
            Private_::T3_::DoIt ();
        }
    }
}

namespace {
    namespace Test5_ModuleGetterSetter_ {
        namespace PRIVATE_ {
            using namespace DataExchange;
            using namespace Execution;
            using namespace Time;
            static const Duration kMinTime_ = 1s;
            struct MyData_ {
                bool               fEnabled = false;
                optional<DateTime> fLastSynchronizedAt;
            };
            struct ModuleGetterSetter_Implementation_MyData_ {
                ModuleGetterSetter_Implementation_MyData_ ()
                    : fOptionsFile_{
                          L"MyModule",
                          [] () -> ObjectVariantMapper {
                              ObjectVariantMapper mapper;
                              mapper.AddClass<MyData_> (initializer_list<ObjectVariantMapper::StructFieldInfo>{
                                  {L"Enabled", StructFieldMetaInfo{&MyData_::fEnabled}},
                                  {L"Last-Synchronized-At", StructFieldMetaInfo{&MyData_::fLastSynchronizedAt}},
                              });
                              return mapper;
                          }(),
                          OptionsFile::kDefaultUpgrader, OptionsFile::mkFilenameMapper (L"Put-Your-App-Name-Here")}
                    , fActualCurrentConfigData_{fOptionsFile_.Read<MyData_> (MyData_{})}
                {
                    Set (fActualCurrentConfigData_); // assure derived data (and changed fields etc) up to date
                }
                MyData_ Get () const
                {
                    return fActualCurrentConfigData_;
                }
                void Set (const MyData_& v)
                {
                    fActualCurrentConfigData_ = v;
                    fOptionsFile_.Write (v);
                }

            private:
                OptionsFile fOptionsFile_;
                MyData_     fActualCurrentConfigData_; // automatically initialized just in time, and externally synchronized
            };

            using Execution::ModuleGetterSetter;
            ModuleGetterSetter<MyData_, ModuleGetterSetter_Implementation_MyData_> sModuleConfiguration_;

            void TestUse1_ ()
            {
                if (sModuleConfiguration_.Get ().fEnabled) {
                    auto n     = sModuleConfiguration_.Get ();
                    n.fEnabled = false;
                    sModuleConfiguration_.Set (n);
                }
            }
            void TestUse2_ ()
            {
                sModuleConfiguration_.Update ([] (MyData_ data) { MyData_ result = data; if (result.fLastSynchronizedAt.has_value () and *result.fLastSynchronizedAt + kMinTime_ > DateTime::Now ()) { result.fLastSynchronizedAt = DateTime::Now (); } return result; });
            }
            void TestUse3_ ()
            {
                if (sModuleConfiguration_.Update ([] (const MyData_& data) -> optional<MyData_> {  if (data.fLastSynchronizedAt.has_value () and *data.fLastSynchronizedAt + kMinTime_ > DateTime::Now ()) { MyData_ result = data; result.fLastSynchronizedAt = DateTime::Now (); return result; } return {}; })) {
                    // e.g. trigger someone to wakeup and used changes?
                }
            }
        }
        void DoAll ()
        {
            PRIVATE_::TestUse1_ ();
            PRIVATE_::TestUse2_ ();
            PRIVATE_::TestUse3_ ();
        }
    }
}

namespace {
    void DoRegressionTests_ ()
    {
        Execution::Logger::Activator logMgrActivator; // needed for OptionsFile test
        Test1_Function_ ();
        Test2_CommandLine_ ();
        Test3_::DoAll ();
        Test4_ConstantProperty_::DoAll ();
        Test5_ModuleGetterSetter_::DoAll ();
    }
}

int main ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
{
    Stroika::TestHarness::Setup ();
    return Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "ForwardChainer.h"
#include "AtomSpaceWrapper.h"
#include "utils/NMPrinter.h"
#include "rules/Rules.h"

#include <opencog/util/Logger.h>
#include <opencog/util/mt19937ar.h>

#include <boost/variant.hpp>
#include <time.h>

using std::vector;
using std::cout;
using std::endl;

namespace opencog {
namespace pln {

ForwardChainer::ForwardChainer()
{
    float minConfidence = FWD_CHAIN_MIN_CONFIDENCE;
    float probStack = FWD_CHAIN_PROB_STACK;
    float probGlobal = FWD_CHAIN_PROB_GLOBAL;
}

ForwardChainer::~ForwardChainer()
{
}

pHandle ForwardChainer::fwdChainToTarget(int& maxRuleApps, meta target)
{
    // Should usually only be one (or none).
    pHandleSeq results = fwdChain(maxRuleApps, target);
    if (results.empty())
        return PHANDLE_UNDEFINED;
    else
        return results[0];
}

// Static/Shared random number generator
RandGen* ForwardChainer::rng = NULL;

RandGen* ForwardChainer::getRNG() {
    if (!rng)
        rng = new opencog::MT19937RandGen((unsigned long) time(NULL));
    return rng;
}

void ForwardChainer::printVertexVectorHandles(std::vector< Vertex > hs)
{
    bool firstPrint = true;
    cout << "< ";
    foreach(Vertex v, hs) {
        if (firstPrint) {
            firstPrint = false;
        } else {
            cout << ", ";
        }
        //cout << boost::get<Handle>(v).value();
        cout << v;
    }
    cout << " >";
}

// Possibly should be elsewhere.
// Finds an input filter that has all the constraints, including between arguments.
// inputFilter doesn't include those constraints.
// Sometimes there is more than one input filter available (e.g. for SimSubstRule)
std::set<std::vector<BBvtree> > getFilters(Rule * r)
{
    //meta i2oType(const std::vector<Vertex>& h) const

    //! @todo extend this for other rules (probably separately for each one)
    // generic target for this rule
//    meta generic_target(new vtree(mva((pHandle)ASSOCIATIVE_LINK,
//                                         vtree(CreateVar(GET_ASW)),
//                                         vtree(CreateVar(GET_ASW))
//                                         )));

    std::vector<meta> inputFilter(r->getInputFilter());

    // convert them to BoundVertex instances.
    // This should all probably be refactored.

    Btr<std::vector<BBvtree> > filter(new std::vector<BBvtree>);

    //std::copy(inputFilter.begin(), inputFilter.end(), filter->begin());

    foreach(meta item, inputFilter) {
        BBvtree Btr_bound_item(new BoundVTree(*item)); // not bound yet, it just means it can be bound
        filter->push_back(Btr_bound_item);
    }

    //return makeSingletonSet(filter);

    Rule::setOfMPs ret;
    ret.insert(*filter);
    return ret;

    meta generic_target(new vtree(mva((pHandle)ASSOCIATIVE_LINK,
                                         mva((pHandle)ATOM),
                                         mva((pHandle)ATOM)
                                         )));

    //cout << "getFilters";
    rawPrint(generic_target->begin(), 2);
//    cout << rawPrint(*generic_target,generic_target->begin(),0);

    return r->o2iMeta(generic_target);
}

pHandleSeq ForwardChainer::fwdChain(int maxRuleApps, meta target)
{
    pHandleSeq results;

    while (maxRuleApps > 0) {
        //cout << "steps remaining: " << maxRuleApps << endl;
        bool appliedRule = false;

        // Get the next Rule (no restrictions)
        foreach(Rule *r, rp) { // to avoid needing a nextRule method.
            //cout << "Using " << r->getName() << endl;

            // Find the possible vector(s) of arguments for it
            std::set<std::vector<BBvtree> > filters(r->fullInputFilter());

            // For each such vector:
            foreach(std::vector<BBvtree> f, filters) {
                // find a vector of Atoms that matches it
                Btr<vector<BoundVertex> > args;
                args = findAllArgs(f);
                // check for validity (~redundant)

                //cout << "FWDCHAIN arguments ";
                //printVertexVectorHandles(args); // takes Vertexes not BoundVertexes
                //cout << " are valid? " <<endl;

                bool foundArguments = !args->empty();//true;// = r->validate(args);

                if (!foundArguments) {
                    //cout << "FWDCHAIN args not valid" << endl;
                } else {
                    //cout << "FWDCHAIN args valid" << endl;

                    // do the rule computation etc

                    Vertex V=((r->compute(*args)).GetValue());
                    pHandle out=boost::get<pHandle>(V);
                    const TruthValue& tv=GET_ASW->getTV(out);
                    //cout<<printTV(out)<<'\n';

                    if (!tv.isNullTv() && tv.getCount() > minConfidence) {
                        maxRuleApps--;
                        appliedRule = true;
                        if (target) { // Match it against the target
                            // Adapted from in Rule::validate
                            typedef weak_atom< meta > vertex_wrapper;
                            vertex_wrapper mp(target);

                            if (mp(out)) {
                                results.push_back(out);
                                return results;
                            }
                        } else
                            results.push_back(out);
                        //cout<<"Output\n";
                        NMPrinter np;
                        np.print(out);
                    } else {
                        // Remove atom if not satisfactory
                        //GET_ASW->removeAtom(_v2h(V));
                    }
                }
            }
        }
        // If it iterated through all Rules and couldn't find any suitable
        // input in the AtomSpace. Exit to prevent an infinite loop!
        if (!appliedRule) return results;
    }

    return results;
}

Btr<std::set<BoundVertex> > ForwardChainer::getMatching(const meta target)
{
    // Just look it up via LookupRule
    LookupRule lookup(GET_ASW);
    Btr<std::set<BoundVertex> > matches;

//    std::cout << "getMatching: target: ";
    rawPrint(target->begin(), 5);

    matches = lookup.attemptDirectProduction(target);

    return matches;
}

Btr<vector<BoundVertex> > ForwardChainer::findAllArgs(std::vector<BBvtree> filter)
{
    Btr<vector<BoundVertex> > args(new vector<BoundVertex>);

    //Btr<bindingsT> bindings(new BindingsT());
    Btr<bindingsT> bindings(new std::map<pHandle, pHandle>);

    bool match = findAllArgs(filter, args, 0, bindings);

    return args;
}

bool ForwardChainer::findAllArgs(std::vector<BBvtree> filter, Btr<std::vector<BoundVertex> > args,
                                 uint current_arg, Btr<bindingsT> bindings)
{
    if (current_arg >= filter.size())
        return true;

//    std::cout << "arg #" << current_arg << std::endl;

    BoundVertex bv;

    BBvtree f;
    f = filter[current_arg];
    // TODO also subst in any FWVar bindings so far
    //Btr<bindingsT> bindings(NULL); // should be a parameter to this method.

    //meta virtualized_target(bindings ? bind_vtree(*f,*bindings) : meta(new vtree(*f)));
    //meta virtualized_target(bindings ? bind_vtree(*f,*bindings) : meta(new vtree(*f)));
    meta virtualized_target(bind_vtree(*f,*bindings));
    //meta virtualized_target(meta(new vtree(*f)));
    ForceAllLinksVirtual(virtualized_target);

    Btr<std::set<BoundVertex> > choices;
    choices = getMatching(virtualized_target); // bad_get during LookupRule... (if you use non-FWVars for that thing)

    // pick one of the candidates at random to be the bv

//    std::cout << "choices size: " << choices->size() << std::endl;
    // random selection
    //! @todo sort based on strength and exponential random select
    //pHandle randArg;
    if (choices->size() == 0) {
//        std::cout << "backtracking" << std::endl;
        return false;
    }

    //std::cout << "choices: " << (*choices) << std::endl;

//    foreach (BoundVertex tmp, *choices)
//        std::cout << tmp.GetValue().which() << std::endl;

    // Alternative: is there some OpenCog library function to randomly select an item from a set?
    std::vector<BoundVertex> ordered_choices;
//    std::copy(choices->begin(), choices->end(), ordered_choices.begin());
    foreach (BoundVertex tmp, *choices) {
        //std::cout << _v2h(tmp.GetValue()) << std::endl;
        ordered_choices.push_back(tmp);
    }

    while (ordered_choices.size() > 0) {
        int index = (int) (getRNG()->randfloat() * ordered_choices.size() );
        //randArg = choices[index];

        bv = ordered_choices[index];
        ordered_choices.erase(ordered_choices.begin() + index);

        //choices.erase(choices.begin() + index);
        //args[i] = randArg;

        //boost::get<pHandle>(args[i]);

//        std::cout << "arg #" << current_arg << std::endl;
        NMPrinter np;
//        std::cout << "Using atom: " << std::endl;
        np.print(_v2h(bv.GetValue()));

        // Separate bindings before and after applying this, in case backtracking is necessary
        Btr<bindingsT> new_bindings(new std::map<pHandle, pHandle>);

        // Pass down all the bindings so far, plus any for this slot.
        foreach(hpair hp, *bindings)
            new_bindings->insert(hp);
        foreach(hpair hp, *bv.bindings)
            new_bindings->insert(hp);

        //(*args)[current_arg] = bv;
        args->push_back(bv);

        // Whether the rest of the slots are successfully filled, when we use bv for this slot
        bool rest_filled = findAllArgs(filter, args, current_arg+1, new_bindings);
        if (rest_filled)
            return true;

        args-> pop_back();
//        else // tacky code to prevent more than one try
//            break;
    }

//    std::cout << "backtracking" << std::endl;

    return false;
}

}} // namespace opencog::pln

<commit_msg>Remove obsolete comment<commit_after>/*
 * Copyright (C) 2008 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "ForwardChainer.h"
#include "AtomSpaceWrapper.h"
#include "utils/NMPrinter.h"
#include "rules/Rules.h"

#include <opencog/util/Logger.h>
#include <opencog/util/mt19937ar.h>

#include <boost/variant.hpp>
#include <time.h>

using std::vector;
using std::cout;
using std::endl;

namespace opencog {
namespace pln {

ForwardChainer::ForwardChainer()
{
    float minConfidence = FWD_CHAIN_MIN_CONFIDENCE;
    float probStack = FWD_CHAIN_PROB_STACK;
    float probGlobal = FWD_CHAIN_PROB_GLOBAL;
}

ForwardChainer::~ForwardChainer()
{
}

pHandle ForwardChainer::fwdChainToTarget(int& maxRuleApps, meta target)
{
    // Should usually only be one (or none).
    pHandleSeq results = fwdChain(maxRuleApps, target);
    if (results.empty())
        return PHANDLE_UNDEFINED;
    else
        return results[0];
}

// Static/Shared random number generator
RandGen* ForwardChainer::rng = NULL;

RandGen* ForwardChainer::getRNG() {
    if (!rng)
        rng = new opencog::MT19937RandGen((unsigned long) time(NULL));
    return rng;
}

void ForwardChainer::printVertexVectorHandles(std::vector< Vertex > hs)
{
    bool firstPrint = true;
    cout << "< ";
    foreach(Vertex v, hs) {
        if (firstPrint) {
            firstPrint = false;
        } else {
            cout << ", ";
        }
        //cout << boost::get<Handle>(v).value();
        cout << v;
    }
    cout << " >";
}

// Possibly should be elsewhere.
// Finds an input filter that has all the constraints, including between arguments.
// inputFilter doesn't include those constraints.
// Sometimes there is more than one input filter available (e.g. for SimSubstRule)
std::set<std::vector<BBvtree> > getFilters(Rule * r)
{
    //meta i2oType(const std::vector<Vertex>& h) const

    //! @todo extend this for other rules (probably separately for each one)
    // generic target for this rule
//    meta generic_target(new vtree(mva((pHandle)ASSOCIATIVE_LINK,
//                                         vtree(CreateVar(GET_ASW)),
//                                         vtree(CreateVar(GET_ASW))
//                                         )));

    std::vector<meta> inputFilter(r->getInputFilter());

    // convert them to BoundVertex instances.
    // This should all probably be refactored.

    Btr<std::vector<BBvtree> > filter(new std::vector<BBvtree>);

    //std::copy(inputFilter.begin(), inputFilter.end(), filter->begin());

    foreach(meta item, inputFilter) {
        BBvtree Btr_bound_item(new BoundVTree(*item)); // not bound yet, it just means it can be bound
        filter->push_back(Btr_bound_item);
    }

    //return makeSingletonSet(filter);

    Rule::setOfMPs ret;
    ret.insert(*filter);
    return ret;

    meta generic_target(new vtree(mva((pHandle)ASSOCIATIVE_LINK,
                                         mva((pHandle)ATOM),
                                         mva((pHandle)ATOM)
                                         )));

    //cout << "getFilters";
    rawPrint(generic_target->begin(), 2);
//    cout << rawPrint(*generic_target,generic_target->begin(),0);

    return r->o2iMeta(generic_target);
}

pHandleSeq ForwardChainer::fwdChain(int maxRuleApps, meta target)
{
    pHandleSeq results;

    while (maxRuleApps > 0) {
        //cout << "steps remaining: " << maxRuleApps << endl;
        bool appliedRule = false;

        // Get the next Rule (no restrictions)
        foreach(Rule *r, rp) { // to avoid needing a nextRule method.
            //cout << "Using " << r->getName() << endl;

            // Find the possible vector(s) of arguments for it
            std::set<std::vector<BBvtree> > filters(r->fullInputFilter());

            // For each such vector:
            foreach(std::vector<BBvtree> f, filters) {
                // find a vector of Atoms that matches it
                Btr<vector<BoundVertex> > args;
                args = findAllArgs(f);
                // check for validity (~redundant)

                //cout << "FWDCHAIN arguments ";
                //printVertexVectorHandles(args); // takes Vertexes not BoundVertexes
                //cout << " are valid? " <<endl;

                bool foundArguments = !args->empty();//true;// = r->validate(args);

                if (!foundArguments) {
                    //cout << "FWDCHAIN args not valid" << endl;
                } else {
                    //cout << "FWDCHAIN args valid" << endl;

                    // do the rule computation etc

                    Vertex V=((r->compute(*args, PHANDLE_UNDEFINED, false)).GetValue());
                    pHandle out=boost::get<pHandle>(V);
                    const TruthValue& tv=GET_ASW->getTV(out);
                    //cout<<printTV(out)<<'\n';

                    if (!tv.isNullTv() && tv.getCount() > minConfidence) {
                        maxRuleApps--;
                        appliedRule = true;
                        if (target) { // Match it against the target
                            // Adapted from in Rule::validate
                            typedef weak_atom< meta > vertex_wrapper;
                            vertex_wrapper mp(target);

                            if (mp(out)) {
                                results.push_back(out);
                                return results;
                            }
                        } else
                            results.push_back(out);
                        //cout<<"Output\n";
                        NMPrinter np;
                        np.print(out);
                    } else {
                        // Remove atom if not satisfactory
                        //GET_ASW->removeAtom(_v2h(V));
                    }
                }
            }
        }
        // If it iterated through all Rules and couldn't find any suitable
        // input in the AtomSpace. Exit to prevent an infinite loop!
        if (!appliedRule) return results;
    }

    return results;
}

Btr<std::set<BoundVertex> > ForwardChainer::getMatching(const meta target)
{
    // Just look it up via LookupRule
    LookupRule lookup(GET_ASW);
    Btr<std::set<BoundVertex> > matches;

//    std::cout << "getMatching: target: ";
    rawPrint(target->begin(), 5);

    matches = lookup.attemptDirectProduction(target);

    return matches;
}

Btr<vector<BoundVertex> > ForwardChainer::findAllArgs(std::vector<BBvtree> filter)
{
    Btr<vector<BoundVertex> > args(new vector<BoundVertex>);

    //Btr<bindingsT> bindings(new BindingsT());
    Btr<bindingsT> bindings(new std::map<pHandle, pHandle>);

    bool match = findAllArgs(filter, args, 0, bindings);

    return args;
}

bool ForwardChainer::findAllArgs(std::vector<BBvtree> filter, Btr<std::vector<BoundVertex> > args,
                                 uint current_arg, Btr<bindingsT> bindings)
{
    if (current_arg >= filter.size())
        return true;

//    std::cout << "arg #" << current_arg << std::endl;

    BoundVertex bv;

    BBvtree f;
    f = filter[current_arg];
    // TODO also subst in any FWVar bindings so far
    //Btr<bindingsT> bindings(NULL); // should be a parameter to this method.

    //meta virtualized_target(bindings ? bind_vtree(*f,*bindings) : meta(new vtree(*f)));
    //meta virtualized_target(bindings ? bind_vtree(*f,*bindings) : meta(new vtree(*f)));
    meta virtualized_target(bind_vtree(*f,*bindings));
    //meta virtualized_target(meta(new vtree(*f)));
    ForceAllLinksVirtual(virtualized_target);

    Btr<std::set<BoundVertex> > choices;
    choices = getMatching(virtualized_target);

    // pick one of the candidates at random to be the bv

//    std::cout << "choices size: " << choices->size() << std::endl;
    // random selection
    //! @todo sort based on strength and exponential random select
    //pHandle randArg;
    if (choices->size() == 0) {
//        std::cout << "backtracking" << std::endl;
        return false;
    }

    //std::cout << "choices: " << (*choices) << std::endl;

//    foreach (BoundVertex tmp, *choices)
//        std::cout << tmp.GetValue().which() << std::endl;

    // Alternative: is there some OpenCog library function to randomly select an item from a set?
    std::vector<BoundVertex> ordered_choices;
//    std::copy(choices->begin(), choices->end(), ordered_choices.begin());
    foreach (BoundVertex tmp, *choices) {
        //std::cout << _v2h(tmp.GetValue()) << std::endl;
        ordered_choices.push_back(tmp);
    }

    while (ordered_choices.size() > 0) {
        int index = (int) (getRNG()->randfloat() * ordered_choices.size() );
        //randArg = choices[index];

        bv = ordered_choices[index];
        ordered_choices.erase(ordered_choices.begin() + index);

        //choices.erase(choices.begin() + index);
        //args[i] = randArg;

        //boost::get<pHandle>(args[i]);

//        std::cout << "arg #" << current_arg << std::endl;
        NMPrinter np;
//        std::cout << "Using atom: " << std::endl;
        np.print(_v2h(bv.GetValue()));

        // Separate bindings before and after applying this, in case backtracking is necessary
        Btr<bindingsT> new_bindings(new std::map<pHandle, pHandle>);

        // Pass down all the bindings so far, plus any for this slot.
        foreach(hpair hp, *bindings)
            new_bindings->insert(hp);
        foreach(hpair hp, *bv.bindings)
            new_bindings->insert(hp);

        //(*args)[current_arg] = bv;
        args->push_back(bv);

        // Whether the rest of the slots are successfully filled, when we use bv for this slot
        bool rest_filled = findAllArgs(filter, args, current_arg+1, new_bindings);
        if (rest_filled)
            return true;

        args-> pop_back();
//        else // tacky code to prevent more than one try
//            break;
    }

//    std::cout << "backtracking" << std::endl;

    return false;
}

}} // namespace opencog::pln

<|endoftext|>


<commit_before>#include <iostream>
#include <stdio.h>
#include <fstream>
#include <vector>
//#include <map>
//#include <set>
#include <unordered_set>
//#include <unordered_map>
#include <cmath>
#include <algorithm>

// #include <gnuplot-iostream.h>
#include <assert.h>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>

#include "vector3d.hpp"
#include "swiss_to_lat_lon.hpp"
#include "height_map.hpp"

const int horizon_angles = 360;
const int tile_size = 40;

namespace po = boost::program_options;

struct pos_hoz {
    vector3d pos;
    vector3d norm;
    short elevation_angles[horizon_angles];
    pos_hoz() : pos(0,0,0), norm(0,0,0) {
        memset(elevation_angles, 0, sizeof(short) * horizon_angles);
    }
};

bool EQ_DBL(double a, double b){
    return std::abs(a-b)<EPS_DBL;
}

int main(int ac, char** av) {

    bool test = false;
    //Variables to be assigned by program options
    double height_map_resolution;
    double north_bound;
    double south_bound;
    double east_bound;
    double west_bound;

    std::string input_file;
    std::string output_dir;
    bool verbose = false;

    // Declare the supported options.
    po::options_description op_desc("Allowed options");
    op_desc.add_options()
    ("help", "print options table")
    ("input-file,i", po::value<std::string>(&input_file), "File containing height map data in x<space>y<space>z<newline> swiss coordinates format")
    ("output-dir,o", po::value<std::string>(&output_dir), "Directory for output files (default data_out_<date_time>)")
    ("resolution,R", po::value<double>(&height_map_resolution)->default_value(25.0), "resolution of data (default: 25.0)")
    ("nmax",po::value<double>(&north_bound)->default_value(1e100), "maximum north coordinate to be treated (default 1e100)")
    ("nmin",po::value<double>(&south_bound)->default_value(-1e100), "minimum north coordinate to be treated (default -1e100)")
    ("emax",po::value<double>(&east_bound)->default_value(1e100), "maximum east coordinate to be treated (default 1e100)")
    ("emin",po::value<double>(&west_bound)->default_value(-1e100), "minimum east coordinate to be treated (default -1e100)")
    ("verbose, v", "Verbose: output lots of text")
    ;

    po::positional_options_description pd;
    pd.add("input-file", 1).add("output-file", 1);

    po::variables_map vm;
    po::store(po::parse_command_line(ac, av, op_desc), vm);
    po::notify(vm);

    if (vm.count("help")) {
        std::cout <<"ComputeHorizons [options] [input file] [output base]"<<std::endl<< op_desc << std::endl;
        return 1;
    }

    if (vm.count("verbose")){
        verbose = true;
    }
    if(!vm.count("input-file")){
        std::cout << "Input file must be specified" << std::endl;
        exit(255);
    }
    if(!vm.count("output-dir")){
        std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        std::string time_string(30, 0);
        std::strftime(&time_string[0], time_string.size(), "%Yx%mx%dT%Hx%Mx%S", std::localtime(&now));
        output_dir = std::string("hoz_out_")+time_string;
        std::cout << "Output directory will be: "+output_dir << std::endl;
    }

    //create output directory
    boost::filesystem::path dir(output_dir);
    if(!boost::filesystem::create_directory(dir)) {
        std::cout << "Failed to creat output directory" << "\n";
        exit(255);
    }
    std::ifstream ifs(input_file);
    if (!ifs.is_open())
        throw std::runtime_error("could not open file : " + std::string(input_file));

    height_map grid_points(ifs, south_bound, north_bound, east_bound, west_bound);

    //grid_points is a height_map, an unordered_set of all points in bounding box with
    //the maximum and minimum x,y,h of all values stored.

    std::pair<double,double> NE = swiss_to_lat_lon(grid_points.xmax()+height_map_resolution/2.0, grid_points.ymax()+height_map_resolution/2.0);
    std::pair<double,double> SW = swiss_to_lat_lon(grid_points.xmin()-height_map_resolution/2.0, grid_points.ymin()-height_map_resolution/2.0);

    std::cout << "NE: " << grid_points.xmax() <<", " << grid_points.ymax() << " SW: "<< grid_points.xmin() << " , " << grid_points.ymin() <<  std::endl;
    std::cout  << "NE: " << NE.first <<", " << NE.second << " SW: "<< SW.first << ", " << SW.second <<  std::endl;
    std::cout << "Maximum height: " << grid_points.hmax() << std::endl;
    std::cout << "Number of points in dataset: " << grid_points.size() << std::endl;

    if(test){
        double y_test = height_map_resolution*floor(601430.0/height_map_resolution);
        double x_test = height_map_resolution*floor(126243.0/height_map_resolution);
        auto it_v = grid_points.find_point(vector3d(x_test,y_test,0));      //get the gridpoint from the set
        std::cout << "Test point: " << x_test <<" "<< y_test << std::endl;
        std::cout << "Resolution: " << height_map_resolution << ", tile size: "<< tile_size << std::endl;
        vector3d v = *it_v;
        double elevation_angles[360];
        int theta_start = 0;
        int theta_end = 360;

        //        time_t start_time  = time(NULL);
        clock_t t = clock();
        for(int theta = theta_start;theta<theta_end;theta++){
            elevation_angles[theta] = grid_points.compute_elevation_angle(v, theta, height_map_resolution, 1.0);
        }
        double run_time = ((double)(clock()-t))/CLOCKS_PER_SEC;
        //        double run_time = difftime(time(NULL), start_time);
        std::cout << "phi = [";
        for(int theta = theta_start;theta<theta_end;theta++){
            std::cout << elevation_angles[theta] << ";";
        }
        std::cout << "];" << std::endl;
        std::cout << "runtime test point: " << run_time << std::endl;
        std::cout << "estimated runtime all points: " << run_time*grid_points.size() << std::endl;

        return 0;
    }

    std::string file_name;
    std::ofstream ofs;

    time_t start_time  = time(NULL);
    int N=0;
    int NT=0;

    int first_tile_y = (int) (grid_points.ymin()+10.0*height_map_resolution);
    int first_tile_x = (int) (grid_points.xmin()+10.0*height_map_resolution);
    int N_tiles_x = (int) ceil((grid_points.xmax()-grid_points.xmin()-20.0*height_map_resolution)/tile_size);
    int N_tiles_y = (int) ceil((grid_points.ymax()-grid_points.ymin()-20.0*height_map_resolution)/tile_size);

    pos_hoz tile_points[tile_size*tile_size];

    for(int x_tile = 0;x_tile<N_tiles_x; x_tile++){
        for(int y_tile = 0; y_tile<N_tiles_y;y_tile++){
            double coord_x = (first_tile_x + height_map_resolution*tile_size*x_tile);
            double coord_x_end = coord_x+height_map_resolution*tile_size;
            int tile_point = 0;
            while(coord_x < coord_x_end){
                double coord_y = (first_tile_y + height_map_resolution*tile_size*y_tile);
                double coord_y_end = coord_y+height_map_resolution*tile_size;
                while(coord_y < coord_y_end){

                    //get point and points to the north, west, south and east
                    vector3d v(coord_x, coord_y, 0.0);
                    vector3d vN(v.x+height_map_resolution,v.y,0);
                    vector3d vW(v.x,v.y+height_map_resolution,0);
                    vector3d vS(v.x-height_map_resolution,v.y,0);
                    vector3d vE(v.x,v.y-height_map_resolution,0);

                    auto itv=grid_points.find_point(v);
                    auto itE=grid_points.find_point(vE);
                    auto itN=grid_points.find_point(vN);
                    auto itW=grid_points.find_point(vW);
                    auto itS=grid_points.find_point(vS);

                    if (grid_points.is_end(itv) ||grid_points.is_end(itE) || grid_points.is_end(itN) || grid_points.is_end(itW) || grid_points.is_end(itS)){
                        coord_y = coord_y + height_map_resolution;
                        tile_points[tile_point].pos = vector3d(0,0,0);
                        tile_point++;
                        continue;
                        //if one of the neighboring points are not found we continue with the next point
                    }
                    v = *itv;
                    vE = *itE;
                    vN = *itN;
                    vW = *itW;
                    vS = *itS;
                    tile_points[tile_point].pos = v;

                    vector3d Normal = ((((vE-v)^(vN-v))+((vW-v)^(vS-v)))/2).norm();       //normal is the crossproduct of two prependicular differences. Avgd.

                    tile_points[tile_point].norm = Normal;

                    for(int theta=0;theta<horizon_angles;theta++){
                        double phi = grid_points.compute_elevation_angle(v,theta, height_map_resolution, 360.0/horizon_angles);
                        tile_points[tile_point].elevation_angles[theta] = (short)((phi / M_PI_2) * std::numeric_limits<short>::max());
                    }
                    N++;
                    coord_y = coord_y + height_map_resolution;
                    tile_point++;
                    if (N%40==0) {
                        double run_time = difftime(time(NULL), start_time);
                        int rdays = (int)floor(run_time/86400.0);
                        int rhours = (int)floor((run_time-rdays*86400)/3600.0);
                        int rminutes = (int)floor((run_time-rdays*86400.0-rhours*3600.0)/60.0);
                        int rseconds = (int)floor(run_time-rdays*86400.0-rhours*3600.0-rminutes*60.0);
                        double remaining_time = ((grid_points.size() - N)*1.0)*run_time/(N*1.0);
                        int days = (int)floor(remaining_time/86400.0);
                        int hours = (int)floor((remaining_time-days*86400)/3600.0);
                        int minutes = (int)floor((remaining_time-days*86400-hours*3600.0)/60.0);
                        int seconds = (int)floor(remaining_time-days*86400-hours*3600.0-minutes*60.0);
                        double progress = round(1000.0*100.0*(N*1.0)/(grid_points.size()*1.0))/1000.0;
                        if(N > 0){
                            std::cout <<"   Progress: "<< progress <<" %  ("<<N<<", "<<NT<<")  time: "<<rdays<<"d"<<rhours<<":"<<rminutes<<":"<<rseconds<<" time left: "<<days<<"d"<<hours<<":"<<minutes<<":"<<seconds<<"      \r";
                            std::cout.flush();
                        }
                    }

                }
                coord_x = coord_x + height_map_resolution;
            }
            std::string tile_name;
            int tile_x = (first_tile_x + height_map_resolution*tile_size*x_tile);
            int tile_y = (first_tile_y + height_map_resolution*tile_size*y_tile);
            tile_name = output_dir + std::string("/tile_") + std::to_string(tile_x) + std::string("_") + std::to_string(tile_y) + std::string(".hoz");
//            std::cout << std::endl << "tile_name " << tile_name << std::endl;
            ofs.open(tile_name, std::iostream::out | std::iostream::binary);
//            std::cout << "first point" << tile_points[0].pos << "norm: " << tile_points[0].norm<< std::endl;
            //open output file
            if (!ofs.is_open()){
                std::cout << "Can't open output file " << tile_name << std::endl;
            }
            ofs.write((char*)&tile_points[0], sizeof(pos_hoz)*tile_size*tile_size);
            ofs.flush();
            ofs.close();
            NT++;

        }
    }
    return 0;
}

<commit_msg>Don't create empty tiles!<commit_after>#include <iostream>
#include <stdio.h>
#include <fstream>
#include <vector>
//#include <map>
//#include <set>
#include <unordered_set>
//#include <unordered_map>
#include <cmath>
#include <algorithm>

// #include <gnuplot-iostream.h>
#include <assert.h>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>

#include "vector3d.hpp"
#include "swiss_to_lat_lon.hpp"
#include "height_map.hpp"

const int horizon_angles = 360;
const int tile_size = 40;

namespace po = boost::program_options;

struct pos_hoz {
    vector3d pos;
    vector3d norm;
    short elevation_angles[horizon_angles];
    pos_hoz() : pos(0,0,0), norm(0,0,0) {
        memset(elevation_angles, 0, sizeof(short) * horizon_angles);
    }
};

bool EQ_DBL(double a, double b){
    return std::abs(a-b)<EPS_DBL;
}

int main(int ac, char** av) {

    bool test = false;
    //Variables to be assigned by program options
    double height_map_resolution;
    double north_bound;
    double south_bound;
    double east_bound;
    double west_bound;

    std::string input_file;
    std::string output_dir;
    bool verbose = false;

    // Declare the supported options.
    po::options_description op_desc("Allowed options");
    op_desc.add_options()
    ("help", "print options table")
    ("input-file,i", po::value<std::string>(&input_file), "File containing height map data in x<space>y<space>z<newline> swiss coordinates format")
    ("output-dir,o", po::value<std::string>(&output_dir), "Directory for output files (default data_out_<date_time>)")
    ("resolution,R", po::value<double>(&height_map_resolution)->default_value(25.0), "resolution of data (default: 25.0)")
    ("nmax",po::value<double>(&north_bound)->default_value(1e100), "maximum north coordinate to be treated (default 1e100)")
    ("nmin",po::value<double>(&south_bound)->default_value(-1e100), "minimum north coordinate to be treated (default -1e100)")
    ("emax",po::value<double>(&east_bound)->default_value(1e100), "maximum east coordinate to be treated (default 1e100)")
    ("emin",po::value<double>(&west_bound)->default_value(-1e100), "minimum east coordinate to be treated (default -1e100)")
    ("verbose, v", "Verbose: output lots of text")
    ;

    po::positional_options_description pd;
    pd.add("input-file", 1).add("output-file", 1);

    po::variables_map vm;
    po::store(po::parse_command_line(ac, av, op_desc), vm);
    po::notify(vm);

    if (vm.count("help")) {
        std::cout <<"ComputeHorizons [options] [input file] [output base]"<<std::endl<< op_desc << std::endl;
        return 1;
    }

    if (vm.count("verbose")){
        verbose = true;
    }
    if(!vm.count("input-file")){
        std::cout << "Input file must be specified" << std::endl;
        exit(255);
    }
    if(!vm.count("output-dir")){
        std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        std::string time_string(30, 0);
        std::strftime(&time_string[0], time_string.size(), "%Yx%mx%dT%Hx%Mx%S", std::localtime(&now));
        output_dir = std::string("hoz_out_")+time_string;
        std::cout << "Output directory will be: "+output_dir << std::endl;
    }

    //create output directory
    boost::filesystem::path dir(output_dir);
    if(!boost::filesystem::create_directory(dir)) {
        std::cout << "Failed to creat output directory" << "\n";
        exit(255);
    }
    std::ifstream ifs(input_file);
    if (!ifs.is_open())
        throw std::runtime_error("could not open file : " + std::string(input_file));

    height_map grid_points(ifs, south_bound, north_bound, east_bound, west_bound);

    //grid_points is a height_map, an unordered_set of all points in bounding box with
    //the maximum and minimum x,y,h of all values stored.

    std::pair<double,double> NE = swiss_to_lat_lon(grid_points.xmax()+height_map_resolution/2.0, grid_points.ymax()+height_map_resolution/2.0);
    std::pair<double,double> SW = swiss_to_lat_lon(grid_points.xmin()-height_map_resolution/2.0, grid_points.ymin()-height_map_resolution/2.0);

    std::cout << "NE: " << grid_points.xmax() <<", " << grid_points.ymax() << " SW: "<< grid_points.xmin() << " , " << grid_points.ymin() <<  std::endl;
    std::cout  << "NE: " << NE.first <<", " << NE.second << " SW: "<< SW.first << ", " << SW.second <<  std::endl;
    std::cout << "Maximum height: " << grid_points.hmax() << std::endl;
    std::cout << "Number of points in dataset: " << grid_points.size() << std::endl;

    if(test){
        double y_test = height_map_resolution*floor(601430.0/height_map_resolution);
        double x_test = height_map_resolution*floor(126243.0/height_map_resolution);
        auto it_v = grid_points.find_point(vector3d(x_test,y_test,0));      //get the gridpoint from the set
        std::cout << "Test point: " << x_test <<" "<< y_test << std::endl;
        std::cout << "Resolution: " << height_map_resolution << ", tile size: "<< tile_size << std::endl;
        vector3d v = *it_v;
        double elevation_angles[360];
        int theta_start = 0;
        int theta_end = 360;

        //        time_t start_time  = time(NULL);
        clock_t t = clock();
        for(int theta = theta_start;theta<theta_end;theta++){
            elevation_angles[theta] = grid_points.compute_elevation_angle(v, theta, height_map_resolution, 1.0);
        }
        double run_time = ((double)(clock()-t))/CLOCKS_PER_SEC;
        //        double run_time = difftime(time(NULL), start_time);
        std::cout << "phi = [";
        for(int theta = theta_start;theta<theta_end;theta++){
            std::cout << elevation_angles[theta] << ";";
        }
        std::cout << "];" << std::endl;
        std::cout << "runtime test point: " << run_time << std::endl;
        std::cout << "estimated runtime all points: " << run_time*grid_points.size() << std::endl;

        return 0;
    }

    std::string file_name;
    std::ofstream ofs;

    time_t start_time  = time(NULL);
    int N=0;
    int NT=0;

    int first_tile_y = (int) (grid_points.ymin()+10.0*height_map_resolution);
    int first_tile_x = (int) (grid_points.xmin()+10.0*height_map_resolution);
    int N_tiles_x = (int) ceil((grid_points.xmax()-grid_points.xmin()-20.0*height_map_resolution)/tile_size);
    int N_tiles_y = (int) ceil((grid_points.ymax()-grid_points.ymin()-20.0*height_map_resolution)/tile_size);

    pos_hoz tile_points[tile_size*tile_size];
    bool tile_empty = true;

    for(int x_tile = 0;x_tile<N_tiles_x; x_tile++){
        for(int y_tile = 0; y_tile<N_tiles_y;y_tile++){
            double coord_x = (first_tile_x + height_map_resolution*tile_size*x_tile);
            double coord_x_end = coord_x+height_map_resolution*tile_size;
            int tile_point = 0;
            tile_empty = true;
            while(coord_x < coord_x_end){
                double coord_y = (first_tile_y + height_map_resolution*tile_size*y_tile);
                double coord_y_end = coord_y+height_map_resolution*tile_size;
                while(coord_y < coord_y_end){

                    //get point and points to the north, west, south and east
                    vector3d v(coord_x, coord_y, 0.0);
                    vector3d vN(v.x+height_map_resolution,v.y,0);
                    vector3d vW(v.x,v.y+height_map_resolution,0);
                    vector3d vS(v.x-height_map_resolution,v.y,0);
                    vector3d vE(v.x,v.y-height_map_resolution,0);

                    auto itv=grid_points.find_point(v);
                    auto itE=grid_points.find_point(vE);
                    auto itN=grid_points.find_point(vN);
                    auto itW=grid_points.find_point(vW);
                    auto itS=grid_points.find_point(vS);

                    if (grid_points.is_end(itv) ||grid_points.is_end(itE) || grid_points.is_end(itN) || grid_points.is_end(itW) || grid_points.is_end(itS)){
                        coord_y = coord_y + height_map_resolution;
                        tile_points[tile_point].pos = vector3d(0,0,0);
                        tile_point++;
                        continue;
                        //if one of the neighboring points are not found we continue with the next point
                    }
                    v = *itv;
                    vE = *itE;
                    vN = *itN;
                    vW = *itW;
                    vS = *itS;
                    tile_points[tile_point].pos = v;

                    vector3d Normal = ((((vE-v)^(vN-v))+((vW-v)^(vS-v)))/2).norm();       //normal is the crossproduct of two prependicular differences. Avgd.

                    tile_points[tile_point].norm = Normal;

                    for(int theta=0;theta<horizon_angles;theta++){
                        double phi = grid_points.compute_elevation_angle(v,theta, height_map_resolution, 360.0/horizon_angles);
                        tile_points[tile_point].elevation_angles[theta] = (short)((phi / M_PI_2) * std::numeric_limits<short>::max());
                    }
                    tile_empty = false;
                    N++;
                    coord_y = coord_y + height_map_resolution;
                    tile_point++;
                    if (N%40==0) {
                        double run_time = difftime(time(NULL), start_time);
                        int rdays = (int)floor(run_time/86400.0);
                        int rhours = (int)floor((run_time-rdays*86400)/3600.0);
                        int rminutes = (int)floor((run_time-rdays*86400.0-rhours*3600.0)/60.0);
                        int rseconds = (int)floor(run_time-rdays*86400.0-rhours*3600.0-rminutes*60.0);
                        double remaining_time = ((grid_points.size() - N)*1.0)*run_time/(N*1.0);
                        int days = (int)floor(remaining_time/86400.0);
                        int hours = (int)floor((remaining_time-days*86400)/3600.0);
                        int minutes = (int)floor((remaining_time-days*86400-hours*3600.0)/60.0);
                        int seconds = (int)floor(remaining_time-days*86400-hours*3600.0-minutes*60.0);
                        double progress = round(1000.0*100.0*(N*1.0)/(grid_points.size()*1.0))/1000.0;
                        if(N > 0){
                            std::cout <<"   Progress: "<< progress <<" %  ("<<N<<", "<<NT<<")  time: "<<rdays<<"d"<<rhours<<":"<<rminutes<<":"<<rseconds<<" time left: "<<days<<"d"<<hours<<":"<<minutes<<":"<<seconds<<"      \r";
                            std::cout.flush();
                        }
                    }

                }
                coord_x = coord_x + height_map_resolution;
            }
            if(!tile_empty){
                std::string tile_name;
                int tile_x = (first_tile_x + height_map_resolution*tile_size*x_tile);
                int tile_y = (first_tile_y + height_map_resolution*tile_size*y_tile);
                tile_name = output_dir + std::string("/tile_") + std::to_string(tile_x) + std::string("_") + std::to_string(tile_y) + std::string(".hoz");
                //            std::cout << std::endl << "tile_name " << tile_name << std::endl;
                ofs.open(tile_name, std::iostream::out | std::iostream::binary);
                //            std::cout << "first point" << tile_points[0].pos << "norm: " << tile_points[0].norm<< std::endl;
                //open output file
                if (!ofs.is_open()){
                    std::cout << "Can't open output file " << tile_name << std::endl;
                }
                ofs.write((char*)&tile_points[0], sizeof(pos_hoz)*tile_size*tile_size);
                ofs.flush();
                ofs.close();
                NT++;
            }

        }
    }
    return 0;
}

<|endoftext|>


<commit_before><commit_msg>Delete mqBI2qNewton.cc<commit_after><|endoftext|>