<commit_before>#ifndef HERMIT_TASK_REMAPPER_HPP
#define HERMIT_TASK_REMAPPER_HPP

#include <boost/config.hpp>

#include <vector>
#include <exception>
#include <boost/asio.hpp>
#include <boost/asio/system_timer.hpp>
#include <boost/tr1/memory.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>

#ifdef BOOST_NO_0X_HDR_FUTURE
#include <boost/tr1/functional.hpp>
#include <boost/thread.hpp>
#include <boost/ref.hpp>
#else
# ifdef BOOST_NO_LAMBDAS
#include <boost/tr1/functional.hpp>
# endif
#include <future>
#endif

namespace hermit {
  class poller_core {
    public:
      template< typename Func >
        poller_core( boost::asio::io_service &service, Func func,
            boost::posix_time::milliseconds time
            ) : timer( service ), task( func ), interval( time ) {
          timer.expires_from_now( interval );
          timer.async_wait( boost::bind( &poller_core::timeout, this, boost::asio::placeholders::error ) );
        }
      void timeout( const boost::system::error_code &error ) {
        if( !error ) {
          task();
          timer.expires_from_now( interval );
          timer.async_wait( boost::bind( &poller_core::timeout, this, boost::asio::placeholders::error ) );
        }
      }
    private:
      boost::asio::deadline_timer timer;
      std::function< void() > task;
      boost::posix_time::milliseconds interval;
  };

  class poller {
    public:
      template< typename Func >
        poller( boost::asio::io_service &service_, Func func,
            boost::posix_time::milliseconds time
            ) : core( new poller_core( service_, func, time ) ) {}
    private:
      std::shared_ptr< poller_core > core;
  };

  class task_remapper {
    public:
      task_remapper( size_t size ) {
        work.reset( new boost::asio::io_service::work( task_queue ) );
        for( int count = 0; count != size; ++count ) {
#ifdef BOOST_NO_0X_HDR_FUTURE
          end_sync.create_thread( std::bind( &task_remapper::run, this ) );
#else
# ifdef BOOST_NO_LAMBDAS
          end_sync.push_back( std::async( std::launch::async, std::bind( &task_remapper::run, this ) ) );
# else
          end_sync.push_back( std::async( std::launch::async, [&]() { this->run(); } ) );
# endif
#endif
        }
      }
#ifdef BOOST_NO_DELETED_FUNCTIONS
    private:
      task_remapper( const task_remapper& );
      task_remapper& operator=( const task_remapper& );
    public:
#else
      task_remapper( const task_remapper& ) = delete;
      task_remapper& operator=( const task_remapper& ) = delete;
#endif
      ~task_remapper() {
        work.reset();
#ifdef BOOST_NO_0X_HDR_FUTURE
        end_sync.join_all();
#else
        for(
          std::vector< std::future< void > >::iterator iter = end_sync.begin();
          iter != end_sync.end(); ++iter
        ) iter->get();
#endif
      }
      template< typename T >
        void post( T func ) {
          task_queue.post( func );
        }
      template< typename T, typename Time >
        poller post( T func, Time time ) {
          return poller( task_queue, func, time );
        }
      template< typename T >
        void set_epilogue( T func ) {
          epilogue.post( func );
        }
      void sync() {
#ifdef BOOST_NO_0X_HDR_FUTURE
        std::shared_ptr< boost::thread::promise< void > > signal( new boost::thread::promise< void >() );
#else
        std::shared_ptr< std::promise< void > > signal( new std::promise< void >() );
#endif
#ifdef BOOST_NO_LAMBDAS
# ifdef BOOST_NO_0X_HDR_FUTURE
        task_queue.post( std::bind( &boost::thread::promise< void >::set_value, signal ) );
# else
        task_queue.post( std::bind( &std::promise< void >::set_value, signal ) );
# endif
#else
        task_queue.post( [=](){ signal->set_value(); } );
#endif
        signal->get_future().wait();
      }
    private:
      static void null_epilogue() {}
#ifdef BOOST_NO_NOEXCEPT
      void run() {
#else
      void run() noexcept {
#endif
        try {
          task_queue.run();
          epilogue.run();
        } catch ( std::exception &e ) {
          std::cerr << "An exception was thrown from queued tasks. : " << e.what() << std::endl;
          std::cerr << "Aborting." << std::endl;
          std::abort();
        } catch ( ... ) {
          std::cerr << "An exception was thrown from queued tasks." << std::endl;
          std::cerr << "Aborting." << std::endl;
          std::abort();
        }
      }
      std::unique_ptr<boost::asio::io_service::work> work;
      boost::asio::io_service task_queue;
      boost::asio::io_service epilogue;
#ifdef BOOST_NO_0X_HDR_FUTURE
      boost::thread_group end_sync;
#else
      std::vector< std::future< void > > end_sync;
#endif
  };
}

#endif
<commit_msg>ポーリングタスクの間隔をintervalで指定するようにした<commit_after>#ifndef HERMIT_TASK_REMAPPER_HPP
#define HERMIT_TASK_REMAPPER_HPP

#include <boost/config.hpp>

#include <vector>
#include <exception>
#include <boost/asio.hpp>
#include <boost/asio/system_timer.hpp>
#include <boost/tr1/memory.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/numeric/interval.hpp>

#ifdef BOOST_NO_0X_HDR_FUTURE
#include <boost/tr1/functional.hpp>
#include <boost/thread.hpp>
#include <boost/ref.hpp>
#else
# ifdef BOOST_NO_LAMBDAS
#include <boost/tr1/functional.hpp>
# endif
#include <future>
#endif

namespace hermit {
  class poller_core {
    public:
      template< typename Func >
        poller_core( boost::asio::io_service &service, Func func,
            boost::numeric::interval< boost::posix_time::milliseconds > interval_
            ) : timer( service ), task( func ), interval( interval_ ) {
          timer.expires_from_now( upper( interval ) );
          timer.async_wait( boost::bind( &poller_core::timeout, this, boost::asio::placeholders::error ) );
        }
      void timeout( const boost::system::error_code &error ) {
        if( !error ) {

          task();
          timer.expires_from_now( upper( interval ) );
          timer.async_wait( boost::bind( &poller_core::timeout, this, boost::asio::placeholders::error ) );
        }
      }
    private:
      boost::asio::deadline_timer timer;
      std::function< void() > task;
      boost::numeric::interval< boost::posix_time::milliseconds > interval;
  };

  class poller {
    public:
      template< typename Func >
        poller( boost::asio::io_service &service_, Func func,
            boost::numeric::interval< boost::posix_time::milliseconds > interval
            ) : core( new poller_core( service_, func, interval ) ) {}
    private:
      std::shared_ptr< poller_core > core;
  };

  class task_remapper {
    public:
      task_remapper( size_t size ) {
        work.reset( new boost::asio::io_service::work( task_queue ) );
        for( int count = 0; count != size; ++count ) {
#ifdef BOOST_NO_0X_HDR_FUTURE
          end_sync.create_thread( std::bind( &task_remapper::run, this ) );
#else
# ifdef BOOST_NO_LAMBDAS
          end_sync.push_back( std::async( std::launch::async, std::bind( &task_remapper::run, this ) ) );
# else
          end_sync.push_back( std::async( std::launch::async, [&]() { this->run(); } ) );
# endif
#endif
        }
      }
#ifdef BOOST_NO_DELETED_FUNCTIONS
    private:
      task_remapper( const task_remapper& );
      task_remapper& operator=( const task_remapper& );
    public:
#else
      task_remapper( const task_remapper& ) = delete;
      task_remapper& operator=( const task_remapper& ) = delete;
#endif
      ~task_remapper() {
        work.reset();
#ifdef BOOST_NO_0X_HDR_FUTURE
        end_sync.join_all();
#else
        for(
          std::vector< std::future< void > >::iterator iter = end_sync.begin();
          iter != end_sync.end(); ++iter
        ) iter->get();
#endif
      }
      template< typename T >
        void post( T func ) {
          task_queue.post( func );
        }
      template< typename T, typename Time >
        poller post( T func, Time time ) {
          return poller( task_queue, func, boost::numeric::hull( time, time ) );
        }
      template< typename T, typename Time >
        poller post( T func, Time min, Time max ) {
          return poller( task_queue, func, boost::numeric::hull( min, max ) );
        }
      template< typename T >
        void set_epilogue( T func ) {
          epilogue.post( func );
        }
      void sync() {
#ifdef BOOST_NO_0X_HDR_FUTURE
        std::shared_ptr< boost::thread::promise< void > > signal( new boost::thread::promise< void >() );
#else
        std::shared_ptr< std::promise< void > > signal( new std::promise< void >() );
#endif
#ifdef BOOST_NO_LAMBDAS
# ifdef BOOST_NO_0X_HDR_FUTURE
        task_queue.post( std::bind( &boost::thread::promise< void >::set_value, signal ) );
# else
        task_queue.post( std::bind( &std::promise< void >::set_value, signal ) );
# endif
#else
        task_queue.post( [=](){ signal->set_value(); } );
#endif
        signal->get_future().wait();
      }
    private:
      static void null_epilogue() {}
#ifdef BOOST_NO_NOEXCEPT
      void run() {
#else
      void run() noexcept {
#endif
        try {
          task_queue.run();
          epilogue.run();
        } catch ( std::exception &e ) {
          std::cerr << "An exception was thrown from queued tasks. : " << e.what() << std::endl;
          std::cerr << "Aborting." << std::endl;
          std::abort();
        } catch ( ... ) {
          std::cerr << "An exception was thrown from queued tasks." << std::endl;
          std::cerr << "Aborting." << std::endl;
          std::abort();
        }
      }
      std::unique_ptr<boost::asio::io_service::work> work;
      boost::asio::io_service task_queue;
      boost::asio::io_service epilogue;
#ifdef BOOST_NO_0X_HDR_FUTURE
      boost::thread_group end_sync;
#else
      std::vector< std::future< void > > end_sync;
#endif
  };
}

#endif
<|endoftext|>


<commit_before>#pragma once

#include "rapidcheck/gen/Tuple.h"
#include "rapidcheck/detail/ApplyTuple.h"

namespace rc {
namespace gen {
namespace detail {

// Member variables
template <typename Type, typename T>
class Lens<T(Type::*)> {
public:
  typedef T(Type::*MemberPtr);
  typedef Type Target;
  typedef T ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    obj.*m_ptr = std::move(std::forward<Arg>(arg));
  }

private:
  MemberPtr m_ptr;
};

// Member functions with single argument
template <typename Type, typename Ret, typename T>
class Lens<Ret (Type::*)(T)> {
public:
  typedef Ret (Type::*MemberPtr)(T);
  typedef Type Target;
  typedef Decay<T> ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    (obj.*m_ptr)(std::forward<Arg>(arg));
  }

private:
  MemberPtr m_ptr;
};

// Member functions with multiple arguments
template <typename Type, typename Ret, typename T1, typename T2, typename... Ts>
class Lens<Ret (Type::*)(T1, T2, Ts...)> {
public:
  typedef Ret (Type::*MemberPtr)(T1, T2, Ts...);
  typedef Type Target;
  typedef std::tuple<Decay<T1>, Decay<T2>, Decay<Ts>...> ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    rc::detail::applyTuple(
        std::forward<Arg>(arg),
        [&](Decay<T1> &&arg1, Decay<T2> &&arg2, Decay<Ts> &&... args) {
          (obj.*m_ptr)(std::move(arg1), std::move(arg2), std::move(args)...);
        });
  }

private:
  MemberPtr m_ptr;
};

template <typename Member, typename SourceType>
struct Binding {
  Binding(Lens<Member> &&l, Gen<SourceType> &&g)
      : lens(std::move(l))
      , gen(std::move(g)) {}

  Lens<Member> lens;
  Gen<SourceType> gen;
};

template <typename T>
T &deref(T &x) {
  return x;
}

template <typename T>
T &deref(std::unique_ptr<T> &x) {
  return *x;
}

template <typename T>
T &deref(std::shared_ptr<T> &x) {
  return *x;
}

template <typename T, typename Indexes, typename... Lenses>
class BuildMapper;

template <typename T, typename... Lenses, std::size_t... Indexes>
class BuildMapper<T, rc::detail::IndexSequence<Indexes...>, Lenses...> {
public:
  BuildMapper(const Lenses &... lenses)
      : m_lenses(std::move(lenses)...) {}

  T operator()(std::tuple<T, typename Lenses::ValueType...> &&tuple) const {
    T &obj = std::get<0>(tuple);
    auto dummy = {(std::get<Indexes>(m_lenses).set(
                       deref(obj), std::move(std::get<Indexes + 1>(tuple))),
                   0)...};
    (void)dummy; // Silence warning

    return std::move(obj);
  }

private:
  std::tuple<Lenses...> m_lenses;
};

} // namespace detail

template <typename T, typename... Args>
Gen<T> construct(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(
                        std::move(argsTuple),
                        [](Args &&... args) { return T(std::move(args)...); });
                  });
}

template <typename T, typename Arg, typename... Args>
Gen<T> construct() {
  return gen::construct<T>(gen::arbitrary<Arg>(), gen::arbitrary<Args>()...);
}

template <typename T, typename... Args>
Gen<std::unique_ptr<T>> makeUnique(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(
                        std::move(argsTuple),
                        [](Args &&... args) {
                          return std::unique_ptr<T>(new T(std::move(args)...));
                        });
                  });
}

template <typename T, typename... Args>
Gen<std::shared_ptr<T>> makeShared(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(std::move(argsTuple),
                                                  [](Args &&... args) {
                                                    return std::make_shared<T>(
                                                        std::move(args)...);
                                                  });
                  });
}

template <typename Member, typename T>
detail::Binding<Member, T> set(Member member, Gen<T> gen) {
  return detail::Binding<Member, T>(detail::Lens<Member>(member),
                                    std::move(gen));
}

template <typename Member>
detail::Binding<Member, typename detail::Lens<Member>::ValueType>
set(Member member) {
  using T = typename detail::Lens<Member>::ValueType;
  return set(member, gen::arbitrary<T>());
}

template <typename T, typename... Members, typename... SourceTypes>
Gen<T> build(Gen<T> gen, const detail::Binding<Members, SourceTypes> &... bs) {
  using Mapper =
      detail::BuildMapper<T,
                          rc::detail::MakeIndexSequence<sizeof...(Members)>,
                          detail::Lens<Members>...>;

  // GCC HACK - Variadics + lambdas don't work very well in GCC so we use an old
  // fashioned function object (the Mapper thing) to prevent GCC from crashing.
  // Use lambdas and applyTuple once we drop support for the crashing ones.
  return gen::map(gen::tuple(std::move(gen), std::move(bs.gen)...),
                  Mapper(bs.lens...));
}

template <typename T, typename... Members, typename... SourceTypes>
Gen<T> build(const detail::Binding<Members, SourceTypes> &... bs) {
  return build<T>(fn::constant(shrinkable::lambda([] { return T(); })), bs...);
}

} // namespace gen
} // namespace rc
<commit_msg>Remove useless std::move<commit_after>#pragma once

#include "rapidcheck/gen/Tuple.h"
#include "rapidcheck/detail/ApplyTuple.h"

namespace rc {
namespace gen {
namespace detail {

// Member variables
template <typename Type, typename T>
class Lens<T(Type::*)> {
public:
  typedef T(Type::*MemberPtr);
  typedef Type Target;
  typedef T ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    obj.*m_ptr = std::move(std::forward<Arg>(arg));
  }

private:
  MemberPtr m_ptr;
};

// Member functions with single argument
template <typename Type, typename Ret, typename T>
class Lens<Ret (Type::*)(T)> {
public:
  typedef Ret (Type::*MemberPtr)(T);
  typedef Type Target;
  typedef Decay<T> ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    (obj.*m_ptr)(std::forward<Arg>(arg));
  }

private:
  MemberPtr m_ptr;
};

// Member functions with multiple arguments
template <typename Type, typename Ret, typename T1, typename T2, typename... Ts>
class Lens<Ret (Type::*)(T1, T2, Ts...)> {
public:
  typedef Ret (Type::*MemberPtr)(T1, T2, Ts...);
  typedef Type Target;
  typedef std::tuple<Decay<T1>, Decay<T2>, Decay<Ts>...> ValueType;

  Lens(MemberPtr ptr)
      : m_ptr(ptr) {}

  template <typename Arg>
  void set(Target &obj, Arg &&arg) const {
    rc::detail::applyTuple(
        std::forward<Arg>(arg),
        [&](Decay<T1> &&arg1, Decay<T2> &&arg2, Decay<Ts> &&... args) {
          (obj.*m_ptr)(std::move(arg1), std::move(arg2), std::move(args)...);
        });
  }

private:
  MemberPtr m_ptr;
};

template <typename Member, typename SourceType>
struct Binding {
  Binding(Lens<Member> &&l, Gen<SourceType> &&g)
      : lens(std::move(l))
      , gen(std::move(g)) {}

  Lens<Member> lens;
  Gen<SourceType> gen;
};

template <typename T>
T &deref(T &x) {
  return x;
}

template <typename T>
T &deref(std::unique_ptr<T> &x) {
  return *x;
}

template <typename T>
T &deref(std::shared_ptr<T> &x) {
  return *x;
}

template <typename T, typename Indexes, typename... Lenses>
class BuildMapper;

template <typename T, typename... Lenses, std::size_t... Indexes>
class BuildMapper<T, rc::detail::IndexSequence<Indexes...>, Lenses...> {
public:
  BuildMapper(const Lenses &... lenses)
      : m_lenses(lenses...) {}

  T operator()(std::tuple<T, typename Lenses::ValueType...> &&tuple) const {
    T &obj = std::get<0>(tuple);
    auto dummy = {(std::get<Indexes>(m_lenses).set(
                       deref(obj), std::move(std::get<Indexes + 1>(tuple))),
                   0)...};
    (void)dummy; // Silence warning

    return std::move(obj);
  }

private:
  std::tuple<Lenses...> m_lenses;
};

} // namespace detail

template <typename T, typename... Args>
Gen<T> construct(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(
                        std::move(argsTuple),
                        [](Args &&... args) { return T(std::move(args)...); });
                  });
}

template <typename T, typename Arg, typename... Args>
Gen<T> construct() {
  return gen::construct<T>(gen::arbitrary<Arg>(), gen::arbitrary<Args>()...);
}

template <typename T, typename... Args>
Gen<std::unique_ptr<T>> makeUnique(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(
                        std::move(argsTuple),
                        [](Args &&... args) {
                          return std::unique_ptr<T>(new T(std::move(args)...));
                        });
                  });
}

template <typename T, typename... Args>
Gen<std::shared_ptr<T>> makeShared(Gen<Args>... gens) {
  return gen::map(gen::tuple(std::move(gens)...),
                  [](std::tuple<Args...> &&argsTuple) {
                    return rc::detail::applyTuple(std::move(argsTuple),
                                                  [](Args &&... args) {
                                                    return std::make_shared<T>(
                                                        std::move(args)...);
                                                  });
                  });
}

template <typename Member, typename T>
detail::Binding<Member, T> set(Member member, Gen<T> gen) {
  return detail::Binding<Member, T>(detail::Lens<Member>(member),
                                    std::move(gen));
}

template <typename Member>
detail::Binding<Member, typename detail::Lens<Member>::ValueType>
set(Member member) {
  using T = typename detail::Lens<Member>::ValueType;
  return set(member, gen::arbitrary<T>());
}

template <typename T, typename... Members, typename... SourceTypes>
Gen<T> build(Gen<T> gen, const detail::Binding<Members, SourceTypes> &... bs) {
  using Mapper =
      detail::BuildMapper<T,
                          rc::detail::MakeIndexSequence<sizeof...(Members)>,
                          detail::Lens<Members>...>;

  // GCC HACK - Variadics + lambdas don't work very well in GCC so we use an old
  // fashioned function object (the Mapper thing) to prevent GCC from crashing.
  // Use lambdas and applyTuple once we drop support for the crashing ones.
  return gen::map(gen::tuple(std::move(gen), std::move(bs.gen)...),
                  Mapper(bs.lens...));
}

template <typename T, typename... Members, typename... SourceTypes>
Gen<T> build(const detail::Binding<Members, SourceTypes> &... bs) {
  return build<T>(fn::constant(shrinkable::lambda([] { return T(); })), bs...);
}

} // namespace gen
} // namespace rc
<|endoftext|>


<commit_before>#include <resolve_smartpointer.h>

boost::python::object resolve_object(IAAFObjectSP sp)
{

    AxObject ax(sp);

    std::string classname = AxStringToString(ax.GetClassName());

    if (classname == "DataDefinition")
    {
        IAAFDataDefSP spItem = AxQueryInterface<IAAFObject,IAAFDataDef>(sp);
        return boost::python::object(spItem);
    }

    else if (classname == "ContainerDefinition")
    {
        IAAFContainerDefSP spItem = AxQueryInterface<IAAFObject,IAAFContainerDef>(sp);
        return boost::python::object(spItem);
    }

    else if (classname == "EdgeCode")
    {
        IAAFEdgecodeSP spItem = AxQueryInterface<IAAFObject,IAAFEdgecode>(sp);
        return boost::python::object(spItem);
    }

    else if (classname == "OperationDefinition")
    {
        IAAFOperationDefSP spItem = AxQueryInterface<IAAFObject,IAAFOperationDef>(sp);
        return boost::python::object(spItem);
    }

    else if (classname == "ParameterDefinition")
    {
        IAAFParameterDefSP spItem = AxQueryInterface<IAAFObject,IAAFParameterDef>(sp);
        return boost::python::object(spItem);
    }

    else if (classname == "InterpolationDefinition")
    {
        IAAFInterpolationDefSP spItem = AxQueryInterface<IAAFObject,IAAFInterpolationDef>(sp);
        return boost::python::object(spItem);
    }

    #define CASE(T)	\
    else if (classname == #T){	\
    IAAF##T##SP spItem = AxQueryInterface<IAAFObject,IAAF##T>(sp);	\
    return boost::python::object(spItem);}

    CASE(ContentStorage)

    CASE( AIFCDescriptor )
    CASE( ClassDef )
    CASE( CodecDef )
    CASE( CommentMarker )
    CASE( Component )
    CASE( CompositionMob )
    CASE( CompositionMob2 )
    CASE( ConstantValue )
    //CASE( ContainerDef )
    CASE( ContentStorage )
    CASE( ControlPoint )
    CASE( DataDef )
    CASE( DefObject )
    CASE( PluginDef )
    CASE( Dictionary )
    //CASE( Edgecode )
    //CASE( OperationDef )
    CASE( EssenceAccess )
    CASE( EssenceData )
    CASE( EssenceDescriptor )
    CASE( Event )
    CASE( EventMobSlot )
    CASE( File )
    CASE( FileDescriptor )
    CASE( FilmDescriptor )
    CASE( DigitalImageDescriptor )
    CASE( CDCIDescriptor )
//    CASE( EssenceFormat )
    CASE( EssenceGroup )
    CASE( Filler )
    CASE( FindSourceInfo )
    CASE( OperationGroup )
    CASE( GPITrigger )
    CASE( Header )
    CASE( Identification )
//    CASE( InterpolationDef )
    CASE( KLVData )
    CASE( Locator )
    CASE( MasterMob )
    CASE( MasterMob2 )
    CASE( MasterMobEx )
    CASE( MetaDefinition )
    CASE( Mob )
    CASE( MobSlot )
    CASE( NestedScope )
    CASE( NetworkLocator )
    CASE( Object )
    CASE( Parameter )
//    CASE( ParameterDef )
//    CASE( Property )
    CASE( PropertyDef )
//    CASE( PropertyValue )
    CASE( PluginManager )
    CASE( Pulldown )
    CASE( RGBADescriptor )
    CASE( ScopeReference )
    CASE( Segment )
    CASE( Selector )
    CASE( Sequence )
    CASE( SourceClip )
    CASE( SourceMob )
    CASE( SourceReference )
    CASE( StaticMobSlot )
    CASE( TapeDescriptor )
    CASE( TaggedValue )
    CASE( TextLocator )
    CASE( Timecode )
    CASE( TimelineMobSlot )
    CASE( Transition )
    CASE( TIFFDescriptor )
    CASE( TimecodeStream )
    CASE( TimecodeStream12M )
    CASE( TypeDef )
    CASE( TypeDefCharacter )
    CASE( TypeDefIndirect )
    CASE( TypeDefInt )
    CASE( TypeDefRename )
    CASE( TypeDefEnum )
    CASE( TypeDefExtEnum )
    CASE( TypeDefFixedArray )
    CASE( TypeDefRecord )
    CASE( TypeDefSet )
    CASE( TypeDefStream )
    CASE( TypeDefString )
    CASE( TypeDefStrongObjRef )
    CASE( TypeDefWeakObjRef )
    CASE( TypeDefObjectRef )
    CASE( TypeDefOpaque )
    CASE( TypeDefVariableArray )
    CASE( VaryingValue )
    CASE( WAVEDescriptor )
    CASE( RawStorage )
    CASE( RandomRawStorage )
    CASE( GetFileBits )
    CASE( SetFileBits )
    CASE( RandomFile )
    CASE( Endian )
    CASE( SearchSource )
    CASE( EssenceMultiAccess )
    CASE( TypeDefVariableArrayEx )

    // New 1.1 objects.
    CASE( AES3PCMDescriptor )
    CASE( AuxiliaryDescriptor )
    CASE( Component2 )
    CASE( DataDef2 )
    CASE( DataDef3 )
    CASE( DescriptiveFramework )
    CASE( DescriptiveMarker )
    CASE( Dictionary2 )
    CASE( Header2 )
    CASE( ImportDescriptor )
    CASE( KLVDataDefinition )
    CASE( Mob2 )
    CASE( MultipleDescriptor )
    CASE( PCMDescriptor )
    CASE( PhysicalDescriptor )
    CASE( RecordingDescriptor )
    CASE( RGBADescriptor2 )
    CASE( SoundDescriptor )
    CASE( TaggedValueDefinition )
    CASE( TimelineMobSlot2 )

    // New additions for the 1.1.6 release (added since 1.1).
    CASE( BWFImportDescriptor )
    CASE( DataEssenceDescriptor )
    CASE( DescriptiveClip )
    CASE( DescriptiveObject )
    CASE( MPEGVideoDescriptor )
    CASE( RIFFChunk )

    // plugin interfaces
//    CASE( IAAFPlugin )
//    CASE( IAAFClassExtension )
//    CASE( IAAFEssenceStream )
//    CASE( IAAFEssenceDataStream )
//    CASE( IAAFEssenceCodec )
//    CASE( IAAFMultiEssenceCodec )
//    CASE( IAAFEssenceContainer )
//    CASE( IAAFInterpolator )

    #undef CASE

    else
    {
    std::cout <<"* Unable To Resovle" << classname << "\n";
    //throw AxExBadImp( L"unknown IAAFObjectSP type category" );

    return boost::python::object(sp);

    }
}

boost::python::object resolve_typedef(IAAFTypeDefSP spTypeDef)
{

    AxTypeDef axTypeDef(spTypeDef);
    eAAFTypeCategory_t cat = axTypeDef.GetTypeCategory();

    switch( cat )
    {

            #define CASE(T)	\
            case kAAFTypeCat##T :	\
            { \
            IAAFTypeDef##T##SP sp; \
            AxQueryInterface( axTypeDef.GetTypeDefSP(), sp ); \
            return boost::python::object(sp); \
            }

            CASE( Int )
            CASE( Character )
            CASE( StrongObjRef )
            CASE( WeakObjRef )
            CASE( Rename )
            CASE( Enum )
            CASE( FixedArray )
            CASE( Set )
            CASE( Record )
            CASE( Stream )
            CASE( String )
            CASE( ExtEnum )
            CASE( Indirect )
            CASE( Opaque )
            CASE( VariableArray )

            #undef CASE

        case kAAFTypeCatUnknown:
            // FIXME - What to do here?  Get RawAccessType perhaps, but how is that
            // distinquished from encrypted using only the process() argument type?
            break;
        case kAAFTypeCatEncrypted:
            // FIXME - see kAAFTypeCatUnknown above.
            break;

        default:
            throw AxExBadImp( L"unknown type category" );

    }

    return boost::python::object();
}
boost::python::object resolve_IEnumAAF(IUnknownSP sp)
{

    #define CASE(T)	\
    if (isClassType<T>(sp)){	\
    T##SP spItem = AxQueryInterface<IUnknown, T>(sp);	\
    return boost::python::object(spItem);}

    CASE( IEnumAAFClassDefs )
    CASE( IEnumAAFCodecDefs )
    CASE( IEnumAAFCodecFlavours )
    CASE( IEnumAAFComponents )
    CASE( IEnumAAFContainerDefs )
    CASE( IEnumAAFControlPoints )
    CASE( IEnumAAFDataDefs )
    CASE( IEnumAAFIdentifications )
    CASE( IEnumAAFInterpolationDefs )
    CASE( IEnumAAFOperationDefs )
    CASE( IEnumAAFEssenceData )
    CASE( IEnumAAFKLVData )
    CASE( IEnumAAFLoadedPlugins )
    CASE( IEnumAAFLocators )
    CASE( IEnumAAFMobSlots )
    CASE( IEnumAAFMobs )
    CASE( IEnumAAFParameterDefs )
    CASE( IEnumAAFParameters )
    CASE( IEnumAAFProperties )
    CASE( IEnumAAFPropertyDefs )
    CASE( IEnumAAFPropertyValues )
    CASE( IEnumAAFPluginDefs )
    CASE( IEnumAAFPluginLocators )
    CASE( IEnumAAFSegments )
    CASE( IEnumAAFTaggedValues )
    CASE( IEnumAAFTypeDefs )

    CASE( IEnumAAFKLVDataDefs )
    CASE( IEnumAAFTaggedValueDefs )

    #undef CASE

    throw AxExBadImp( L"unknown IUnknownSP type category" );

}

boost::python::object resolve_smartpointer(IUnknownSP sp)
{

    if (isClassType<IAAFObject>(sp))

    {

        IAAFObjectSP spObject = AxQueryInterface<IUnknown,IAAFObject>(sp);

        return resolve_object(spObject);

    }

    else if (isClassType<IAAFTypeDef>(sp))
    {
        IAAFTypeDefSP spObject = AxQueryInterface<IUnknown,IAAFTypeDef>(sp);

        return resolve_typedef(spObject);

    }

    #define CASE(T)	\
    else if (isClassType<IAAF##T>(sp) ){	\
    IAAF##T##SP spItem = AxQueryInterface<IUnknown,IAAF##T>(sp);	\
    return boost::python::object(spItem);}

    CASE(Property)
    CASE(PropertyValue)
    CASE(EssenceFormat)
    CASE(EssenceAccess)
    CASE(EssenceMultiAccess)

    #undef CASE

    else
    {
        //return boost::python::object();

        return resolve_IEnumAAF(sp);
        throw AxExBadImp( L"unknown IUnknownSP type category" );
    }

}

<commit_msg>resolve ClassDef and PropertyDef<commit_after>#include <resolve_smartpointer.h>

boost::python::object resolve_object(IAAFObjectSP sp)
{

    AxObject ax(sp);

    std::string classname = AxStringToString(ax.GetClassName());

    if (classname == "DataDefinition")
    {
        IAAFDataDefSP spItem = AxQueryInterface<IAAFObject,IAAFDataDef>(sp);
        return boost::python::object(spItem);
    }

    else if (classname == "ContainerDefinition")
    {
        IAAFContainerDefSP spItem = AxQueryInterface<IAAFObject,IAAFContainerDef>(sp);
        return boost::python::object(spItem);
    }

    else if (classname == "EdgeCode")
    {
        IAAFEdgecodeSP spItem = AxQueryInterface<IAAFObject,IAAFEdgecode>(sp);
        return boost::python::object(spItem);
    }

    else if (classname == "OperationDefinition")
    {
        IAAFOperationDefSP spItem = AxQueryInterface<IAAFObject,IAAFOperationDef>(sp);
        return boost::python::object(spItem);
    }

    else if (classname == "ParameterDefinition")
    {
        IAAFParameterDefSP spItem = AxQueryInterface<IAAFObject,IAAFParameterDef>(sp);
        return boost::python::object(spItem);
    }

    else if (classname == "InterpolationDefinition")
    {
        IAAFInterpolationDefSP spItem = AxQueryInterface<IAAFObject,IAAFInterpolationDef>(sp);
        return boost::python::object(spItem);
    }

    #define CASE(T)	\
    else if (classname == #T){	\
    IAAF##T##SP spItem = AxQueryInterface<IAAFObject,IAAF##T>(sp);	\
    return boost::python::object(spItem);}

    CASE(ContentStorage)

    CASE( AIFCDescriptor )
//    CASE( ClassDef )
    CASE( CodecDef )
    CASE( CommentMarker )
    CASE( Component )
    CASE( CompositionMob )
    CASE( CompositionMob2 )
    CASE( ConstantValue )
    //CASE( ContainerDef )
    CASE( ContentStorage )
    CASE( ControlPoint )
    CASE( DataDef )
    CASE( DefObject )
    CASE( PluginDef )
    CASE( Dictionary )
    //CASE( Edgecode )
    //CASE( OperationDef )
    CASE( EssenceAccess )
    CASE( EssenceData )
    CASE( EssenceDescriptor )
    CASE( Event )
    CASE( EventMobSlot )
    CASE( File )
    CASE( FileDescriptor )
    CASE( FilmDescriptor )
    CASE( DigitalImageDescriptor )
    CASE( CDCIDescriptor )
//    CASE( EssenceFormat )
    CASE( EssenceGroup )
    CASE( Filler )
    CASE( FindSourceInfo )
    CASE( OperationGroup )
    CASE( GPITrigger )
    CASE( Header )
    CASE( Identification )
//    CASE( InterpolationDef )
    CASE( KLVData )
    CASE( Locator )
    CASE( MasterMob )
    CASE( MasterMob2 )
    CASE( MasterMobEx )
//    CASE( MetaDefinition )
    CASE( Mob )
    CASE( MobSlot )
    CASE( NestedScope )
    CASE( NetworkLocator )
    CASE( Object )
    CASE( Parameter )
//    CASE( ParameterDef )
//    CASE( Property )
//    CASE( PropertyDef )
//    CASE( PropertyValue )
    CASE( PluginManager )
    CASE( Pulldown )
    CASE( RGBADescriptor )
    CASE( ScopeReference )
    CASE( Segment )
    CASE( Selector )
    CASE( Sequence )
    CASE( SourceClip )
    CASE( SourceMob )
    CASE( SourceReference )
    CASE( StaticMobSlot )
    CASE( TapeDescriptor )
    CASE( TaggedValue )
    CASE( TextLocator )
    CASE( Timecode )
    CASE( TimelineMobSlot )
    CASE( Transition )
    CASE( TIFFDescriptor )
    CASE( TimecodeStream )
    CASE( TimecodeStream12M )
    CASE( TypeDef )
    CASE( TypeDefCharacter )
    CASE( TypeDefIndirect )
    CASE( TypeDefInt )
    CASE( TypeDefRename )
    CASE( TypeDefEnum )
    CASE( TypeDefExtEnum )
    CASE( TypeDefFixedArray )
    CASE( TypeDefRecord )
    CASE( TypeDefSet )
    CASE( TypeDefStream )
    CASE( TypeDefString )
    CASE( TypeDefStrongObjRef )
    CASE( TypeDefWeakObjRef )
    CASE( TypeDefObjectRef )
    CASE( TypeDefOpaque )
    CASE( TypeDefVariableArray )
    CASE( VaryingValue )
    CASE( WAVEDescriptor )
    CASE( RawStorage )
    CASE( RandomRawStorage )
    CASE( GetFileBits )
    CASE( SetFileBits )
    CASE( RandomFile )
    CASE( Endian )
    CASE( SearchSource )
    CASE( EssenceMultiAccess )
    CASE( TypeDefVariableArrayEx )

    // New 1.1 objects.
    CASE( AES3PCMDescriptor )
    CASE( AuxiliaryDescriptor )
    CASE( Component2 )
    CASE( DataDef2 )
    CASE( DataDef3 )
    CASE( DescriptiveFramework )
    CASE( DescriptiveMarker )
    CASE( Dictionary2 )
    CASE( Header2 )
    CASE( ImportDescriptor )
    CASE( KLVDataDefinition )
    CASE( Mob2 )
    CASE( MultipleDescriptor )
    CASE( PCMDescriptor )
    CASE( PhysicalDescriptor )
    CASE( RecordingDescriptor )
    CASE( RGBADescriptor2 )
    CASE( SoundDescriptor )
    CASE( TaggedValueDefinition )
    CASE( TimelineMobSlot2 )

    // New additions for the 1.1.6 release (added since 1.1).
    CASE( BWFImportDescriptor )
    CASE( DataEssenceDescriptor )
    CASE( DescriptiveClip )
    CASE( DescriptiveObject )
    CASE( MPEGVideoDescriptor )
    CASE( RIFFChunk )

    // plugin interfaces
//    CASE( IAAFPlugin )
//    CASE( IAAFClassExtension )
//    CASE( IAAFEssenceStream )
//    CASE( IAAFEssenceDataStream )
//    CASE( IAAFEssenceCodec )
//    CASE( IAAFMultiEssenceCodec )
//    CASE( IAAFEssenceContainer )
//    CASE( IAAFInterpolator )

    #undef CASE

    else
    {
    std::cout <<"* Unable To Resovle" << classname << "\n";
    //throw AxExBadImp( L"unknown IAAFObjectSP type category" );

    return boost::python::object(sp);

    }
}

boost::python::object resolve_metadef(IUnknownSP spMetaDef)
{

    if (isClassType<IAAFTypeDef>(spMetaDef) )
    {

        IAAFTypeDefSP spTypeDef =  AxQueryInterface<IUnknown,IAAFTypeDef>(spMetaDef);
        AxTypeDef axTypeDef(spTypeDef);
        eAAFTypeCategory_t cat = axTypeDef.GetTypeCategory();

        switch( cat )
        {

                #define CASE(T)	\
                case kAAFTypeCat##T :	\
                { \
                IAAFTypeDef##T##SP sp; \
                AxQueryInterface( axTypeDef.GetTypeDefSP(), sp ); \
                return boost::python::object(sp); \
                }

                CASE( Int )
                CASE( Character )
                CASE( StrongObjRef )
                CASE( WeakObjRef )
                CASE( Rename )
                CASE( Enum )
                CASE( FixedArray )
                CASE( Set )
                CASE( Record )
                CASE( Stream )
                CASE( String )
                CASE( ExtEnum )
                CASE( Indirect )
                CASE( Opaque )
                CASE( VariableArray )

                #undef CASE

            case kAAFTypeCatUnknown:
                // FIXME - What to do here?  Get RawAccessType perhaps, but how is that
                // distinquished from encrypted using only the process() argument type?
                break;
            case kAAFTypeCatEncrypted:
                // FIXME - see kAAFTypeCatUnknown above.
                break;

            default:
                throw AxExBadImp( L"unknown type category" );

        }
    }

    #define CASE(T)	\
    else if (isClassType<IAAF##T>(spMetaDef) ){	\
    IAAF##T##SP spItem = AxQueryInterface<IUnknown,IAAF##T>(spMetaDef);	\
    return boost::python::object(spItem);}

    CASE(ClassDef)
    CASE(PropertyDef)

    #undef CASE

    else
    {

        throw AxExBadImp( L"unknown typeDef category" );
    }

    return boost::python::object();
}
boost::python::object resolve_IEnumAAF(IUnknownSP sp)
{

    #define CASE(T)	\
    if (isClassType<T>(sp)){	\
    T##SP spItem = AxQueryInterface<IUnknown, T>(sp);	\
    return boost::python::object(spItem);}

    CASE( IEnumAAFClassDefs )
    CASE( IEnumAAFCodecDefs )
    CASE( IEnumAAFCodecFlavours )
    CASE( IEnumAAFComponents )
    CASE( IEnumAAFContainerDefs )
    CASE( IEnumAAFControlPoints )
    CASE( IEnumAAFDataDefs )
    CASE( IEnumAAFIdentifications )
    CASE( IEnumAAFInterpolationDefs )
    CASE( IEnumAAFOperationDefs )
    CASE( IEnumAAFEssenceData )
    CASE( IEnumAAFKLVData )
    CASE( IEnumAAFLoadedPlugins )
    CASE( IEnumAAFLocators )
    CASE( IEnumAAFMobSlots )
    CASE( IEnumAAFMobs )
    CASE( IEnumAAFParameterDefs )
    CASE( IEnumAAFParameters )
    CASE( IEnumAAFProperties )
    CASE( IEnumAAFPropertyDefs )
    CASE( IEnumAAFPropertyValues )
    CASE( IEnumAAFPluginDefs )
    CASE( IEnumAAFPluginLocators )
    CASE( IEnumAAFSegments )
    CASE( IEnumAAFTaggedValues )
    CASE( IEnumAAFTypeDefs )

    CASE( IEnumAAFKLVDataDefs )
    CASE( IEnumAAFTaggedValueDefs )

    #undef CASE

    throw AxExBadImp( L"unknown IUnknownSP type category" );

}

boost::python::object resolve_smartpointer(IUnknownSP sp)
{

    if (isClassType<IAAFObject>(sp))

    {

        IAAFObjectSP spObject = AxQueryInterface<IUnknown,IAAFObject>(sp);

        return resolve_object(spObject);

    }

    else if (isClassType<IAAFMetaDefinition>(sp))
    {
        return resolve_metadef(sp);

    }

    #define CASE(T)	\
    else if (isClassType<IAAF##T>(sp) ){	\
    IAAF##T##SP spItem = AxQueryInterface<IUnknown,IAAF##T>(sp);	\
    return boost::python::object(spItem);}

    CASE(Property)
    CASE(PropertyValue)
    CASE(EssenceFormat)
    CASE(EssenceAccess)
    CASE(EssenceMultiAccess)

    #undef CASE

    else
    {
        //return boost::python::object();

        return resolve_IEnumAAF(sp);
        throw AxExBadImp( L"unknown IUnknownSP type category" );
    }

}

<|endoftext|>


<commit_before>#pragma once

#include <gcl/mp/concepts.hpp>

namespace gcl::mp::value_traits
{
    template <auto... values>
    requires(std::equality_comparable_with<
             decltype(std::get<0>(std::tuple{values...})),
             decltype(values)>&&...) constexpr static auto equal_v = []() consteval
    {
        return ((values == std::get<0>(std::tuple{values...})) && ...);
    }
    ();
    // Only works for Clang yet, since 11.0.0
    // template <auto first_value = int{}, std::equality_comparable_with<decltype(first_value)> auto... values>
    // constexpr static auto equal_v = []() consteval
    // {
    //     return ((values == first_value) && ...);
    // }
    // ();
    template <auto... values>
    constexpr static auto not_equal_v = not equal_v<values...>;
}

namespace gcl::mp::value_traits::tests::equal
{
    static_assert(equal_v<>);
    static_assert(equal_v<true>);
    static_assert(equal_v<true, true>);
    static_assert(equal_v<true, true, true>);
    static_assert(equal_v<true, true, true, true>);

    static_assert(not not_equal_v<true>);
    static_assert(not_equal_v<true, false>);
    static_assert(not_equal_v<false, true>);
    static_assert(not_equal_v<false, true, true>);
    static_assert(not_equal_v<true, false, true>);
    static_assert(not_equal_v<true, true, false>);
    static_assert(not_equal_v<false, true, true, true>);
    static_assert(not_equal_v<true, false, true, true>);
    static_assert(not_equal_v<true, true, false, true>);
    static_assert(not_equal_v<true, true, true, false>);
}<commit_msg>[mp::value_trait] add sequence<values...><commit_after>#pragma once

#include <gcl/mp/concepts.hpp>

namespace gcl::mp::value_traits
{
    template <auto... values>
    struct sequence {
        constexpr static auto size = sizeof...(values);
    };

    template <auto... values>
    requires(std::equality_comparable_with<
             decltype(std::get<0>(std::tuple{values...})),
             decltype(values)>&&...) constexpr static auto equal_v = []() consteval
    {
        return ((values == std::get<0>(std::tuple{values...})) && ...);
    }
    ();
    // Only works for Clang yet, since 11.0.0
    // template <auto first_value = int{}, std::equality_comparable_with<decltype(first_value)> auto... values>
    // constexpr static auto equal_v = []() consteval
    // {
    //     return ((values == first_value) && ...);
    // }
    // ();
    template <auto... values>
    constexpr static auto not_equal_v = not equal_v<values...>;
}

namespace gcl::mp::value_traits::tests::equal
{
    static_assert(equal_v<>);
    static_assert(equal_v<true>);
    static_assert(equal_v<true, true>);
    static_assert(equal_v<true, true, true>);
    static_assert(equal_v<true, true, true, true>);

    static_assert(not not_equal_v<true>);
    static_assert(not_equal_v<true, false>);
    static_assert(not_equal_v<false, true>);
    static_assert(not_equal_v<false, true, true>);
    static_assert(not_equal_v<true, false, true>);
    static_assert(not_equal_v<true, true, false>);
    static_assert(not_equal_v<false, true, true, true>);
    static_assert(not_equal_v<true, false, true, true>);
    static_assert(not_equal_v<true, true, false, true>);
    static_assert(not_equal_v<true, true, true, false>);
}<|endoftext|>


<commit_before>// This file is part of Poseidon.
// Copyleft 2020, LH_Mouse. All wrongs reserved.

#ifndef POSEIDON_UTILITIES_HPP_
#define POSEIDON_UTILITIES_HPP_

#include "fwd.hpp"
#include "static/async_logger.hpp"
#include "core/abstract_timer.hpp"
#include "static/timer_driver.hpp"
#include "core/abstract_async_job.hpp"
#include "core/promise.hpp"
#include "core/future.hpp"
#include "static/worker_pool.hpp"
#include <asteria/utilities.hpp>
#include <cstdio>

namespace poseidon {

using ::asteria::utf8_encode;
using ::asteria::utf8_decode;
using ::asteria::utf16_encode;
using ::asteria::utf16_decode;

using ::asteria::format_string;
using ::asteria::weaken_enum;
using ::asteria::generate_random_seed;
using ::asteria::format_errno;

template<typename... ParamsT>
ROCKET_NOINLINE
bool
do_xlog_format(Log_Level level, const char* file, long line, const char* func,
               const char* templ, const ParamsT&... params)
noexcept
  try {
    // Compose the message.
    ::rocket::tinyfmt_str fmt;
    format(fmt, templ, params...);  // ADL intended
    auto text = fmt.extract_string();

    // Push a new log entry.
    Async_Logger::enqueue(level, file, line, func, ::std::move(text));
    return true;
  }
  catch(exception& stdex) {
    // Ignore this exception, but print a message.
    ::std::fprintf(stderr,
        "WARNING: %s: could not format log: %s\n[exception `%s` thrown from '%s:%ld'\n",
        func, stdex.what(), typeid(stdex).name(), file, line);
    return false;
  }

// Note the format string must be a string literal.
#define POSEIDON_XLOG_(level, ...)  \
    (::poseidon::Async_Logger::is_enabled(level) &&  \
         ::poseidon::do_xlog_format(level, __FILE__, __LINE__, __func__,  \
                                    "" __VA_ARGS__))

#define POSEIDON_LOG_FATAL(...)   POSEIDON_XLOG_(::poseidon::log_level_fatal,  __VA_ARGS__)
#define POSEIDON_LOG_ERROR(...)   POSEIDON_XLOG_(::poseidon::log_level_error,  __VA_ARGS__)
#define POSEIDON_LOG_WARN(...)    POSEIDON_XLOG_(::poseidon::log_level_warn,   __VA_ARGS__)
#define POSEIDON_LOG_INFO(...)    POSEIDON_XLOG_(::poseidon::log_level_info,   __VA_ARGS__)
#define POSEIDON_LOG_DEBUG(...)   POSEIDON_XLOG_(::poseidon::log_level_debug,  __VA_ARGS__)
#define POSEIDON_LOG_TRACE(...)   POSEIDON_XLOG_(::poseidon::log_level_trace,  __VA_ARGS__)

template<typename... ParamsT>
[[noreturn]] ROCKET_NOINLINE
bool
do_xthrow_format(const char* file, long line, const char* func,
                 const char* templ, const ParamsT&... params)
  {
    // Compose the message.
    ::rocket::tinyfmt_str fmt;
    format(fmt, templ, params...);  // ADL intended
    auto text = fmt.extract_string();

    // Push a new log entry.
    if(Async_Logger::is_enabled(log_level_debug))
      Async_Logger::enqueue(log_level_debug, file, line, func,
                            "POSEIDON_THROW: " + text);

    // Throw the exception.
    ::rocket::sprintf_and_throw<::std::runtime_error>(
        "%s: %s\n[thrown from '%s:%ld']",
        func, text.c_str(), file, line);
  }

#define POSEIDON_THROW(...)  \
    (::poseidon::do_xthrow_format(__FILE__, __LINE__, __func__,  \
                                  "" __VA_ARGS__))

// Creates an asynchronous timer. The timer function will be called by
// the timer thread, so thread safety must be taken into account.
template<typename FuncT>
rcptr<Abstract_Timer>
create_async_timer(int64_t next, int64_t period, FuncT&& func)
  {
    // This is the concrete timer class.
    struct Concrete_Timer : Abstract_Timer
      {
        typename ::std::decay<FuncT>::type m_func;

        explicit
        Concrete_Timer(int64_t next, int64_t period, FuncT&& func)
          : Abstract_Timer(next, period),
            m_func(::std::forward<FuncT>(func))
          { }

        void
        do_on_async_timer(int64_t now)
        override
          { this->m_func(now);  }
      };

    // Allocate an abstract timer and insert it.
    auto timer = ::rocket::make_unique<Concrete_Timer>(next, period,
                                           ::std::forward<FuncT>(func));
    return Timer_Driver::insert(::std::move(timer));
  }

// Creates a one-shot timer. The timer is deleted after being triggered.
template<typename FuncT>
rcptr<Abstract_Timer>
create_async_timer_oneshot(int64_t next, FuncT&& func)
  {
    return noadl::create_async_timer(next, 0, ::std::forward<FuncT>(func));
  }

// Creates a periodic timer.
template<typename FuncT>
rcptr<Abstract_Timer>
create_async_timer_periodic(int64_t period, FuncT&& func)
  {
    return noadl::create_async_timer(period, period, ::std::forward<FuncT>(func));
  }

// Enqueues an asynchronous job and returns a future to its result.
// Functions with the same key will always be delivered to the same worker.
template<typename FuncT>
futp<typename ::std::result_of<FuncT ()>::type>
enqueue_async_job_keyed(uintptr_t key, FuncT&& func)
  {
    // // This is the concrete function class.
    struct Concrete_Async_Job : Abstract_Async_Job
      {
        prom<typename ::std::result_of<FuncT ()>::type> m_prom;
        typename ::std::decay<FuncT>::type m_func;

        explicit
        Concrete_Async_Job(uintptr_t key, FuncT&& func)
          : Abstract_Async_Job(key),
            m_func(::std::forward<FuncT>(func))
          { }

        void
        do_execute()
        override
          { this->m_prom.set_value(this->m_func());  }

        void
        do_set_exception(const ::std::exception_ptr& eptr)
        override
          { this->m_prom.set_exception(eptr);  }
      };

    // Allocate a function object.
    auto async = ::rocket::make_unique<Concrete_Async_Job>(key,
                                           ::std::forward<FuncT>(func));
    auto futr = async->m_prom.future();
    Worker_Pool::insert(::std::move(async));
    return futr;
  }

// Enqueues an asynchronous job and returns a future to its result.
// The function is delivered to a random worker.
template<typename FuncT>
futp<typename ::std::result_of<FuncT ()>::type>
enqueue_async_job_random(FuncT&& func)
  {
    // // This is the concrete function class.
    struct Concrete_Async_Job : Abstract_Async_Job
      {
        prom<typename ::std::result_of<FuncT ()>::type> m_prom;
        typename ::std::decay<FuncT>::type m_func;

        explicit
        Concrete_Async_Job(FuncT&& func)
          : Abstract_Async_Job(reinterpret_cast<uintptr_t>(this)),
            m_func(::std::forward<FuncT>(func))
          { }

        void
        do_execute()
        override
          { this->m_prom.set_value(this->m_func());  }

        void
        do_set_exception(const ::std::exception_ptr& eptr)
        override
          { this->m_prom.set_exception(eptr);  }
      };

    // Allocate a function object.
    auto async = ::rocket::make_unique<Concrete_Async_Job>(
                                           ::std::forward<FuncT>(func));
    auto futr = async->m_prom.future();
    Worker_Pool::insert(::std::move(async));
    return futr;
  }

}  // namespace asteria

#endif
<commit_msg>utilities: Move exception logs back to the warning level<commit_after>// This file is part of Poseidon.
// Copyleft 2020, LH_Mouse. All wrongs reserved.

#ifndef POSEIDON_UTILITIES_HPP_
#define POSEIDON_UTILITIES_HPP_

#include "fwd.hpp"
#include "static/async_logger.hpp"
#include "core/abstract_timer.hpp"
#include "static/timer_driver.hpp"
#include "core/abstract_async_job.hpp"
#include "core/promise.hpp"
#include "core/future.hpp"
#include "static/worker_pool.hpp"
#include <asteria/utilities.hpp>
#include <cstdio>

namespace poseidon {

using ::asteria::utf8_encode;
using ::asteria::utf8_decode;
using ::asteria::utf16_encode;
using ::asteria::utf16_decode;

using ::asteria::format_string;
using ::asteria::weaken_enum;
using ::asteria::generate_random_seed;
using ::asteria::format_errno;

template<typename... ParamsT>
ROCKET_NOINLINE
bool
do_xlog_format(Log_Level level, const char* file, long line, const char* func,
               const char* templ, const ParamsT&... params)
noexcept
  try {
    // Compose the message.
    ::rocket::tinyfmt_str fmt;
    format(fmt, templ, params...);  // ADL intended
    auto text = fmt.extract_string();

    // Push a new log entry.
    Async_Logger::enqueue(level, file, line, func, ::std::move(text));
    return true;
  }
  catch(exception& stdex) {
    // Ignore this exception, but print a message.
    ::std::fprintf(stderr,
        "WARNING: %s: could not format log: %s\n[exception `%s` thrown from '%s:%ld'\n",
        func, stdex.what(), typeid(stdex).name(), file, line);
    return false;
  }

// Note the format string must be a string literal.
#define POSEIDON_XLOG_(level, ...)  \
    (::poseidon::Async_Logger::is_enabled(level) &&  \
         ::poseidon::do_xlog_format(level, __FILE__, __LINE__, __func__,  \
                                    "" __VA_ARGS__))

#define POSEIDON_LOG_FATAL(...)   POSEIDON_XLOG_(::poseidon::log_level_fatal,  __VA_ARGS__)
#define POSEIDON_LOG_ERROR(...)   POSEIDON_XLOG_(::poseidon::log_level_error,  __VA_ARGS__)
#define POSEIDON_LOG_WARN(...)    POSEIDON_XLOG_(::poseidon::log_level_warn,   __VA_ARGS__)
#define POSEIDON_LOG_INFO(...)    POSEIDON_XLOG_(::poseidon::log_level_info,   __VA_ARGS__)
#define POSEIDON_LOG_DEBUG(...)   POSEIDON_XLOG_(::poseidon::log_level_debug,  __VA_ARGS__)
#define POSEIDON_LOG_TRACE(...)   POSEIDON_XLOG_(::poseidon::log_level_trace,  __VA_ARGS__)

template<typename... ParamsT>
[[noreturn]] ROCKET_NOINLINE
bool
do_xthrow_format(const char* file, long line, const char* func,
                 const char* templ, const ParamsT&... params)
  {
    // Compose the message.
    ::rocket::tinyfmt_str fmt;
    format(fmt, templ, params...);  // ADL intended
    auto text = fmt.extract_string();

    // Push a new log entry.
    static constexpr auto level = log_level_warn;
    if(Async_Logger::is_enabled(level))
      Async_Logger::enqueue(level, file, line, func, "POSEIDON_THROW: " + text);

    // Throw the exception.
    ::rocket::sprintf_and_throw<::std::runtime_error>(
        "%s: %s\n[thrown from '%s:%ld']",
        func, text.c_str(), file, line);
  }

#define POSEIDON_THROW(...)  \
    (::poseidon::do_xthrow_format(__FILE__, __LINE__, __func__,  \
                                  "" __VA_ARGS__))

// Creates an asynchronous timer. The timer function will be called by
// the timer thread, so thread safety must be taken into account.
template<typename FuncT>
rcptr<Abstract_Timer>
create_async_timer(int64_t next, int64_t period, FuncT&& func)
  {
    // This is the concrete timer class.
    struct Concrete_Timer : Abstract_Timer
      {
        typename ::std::decay<FuncT>::type m_func;

        explicit
        Concrete_Timer(int64_t next, int64_t period, FuncT&& func)
          : Abstract_Timer(next, period),
            m_func(::std::forward<FuncT>(func))
          { }

        void
        do_on_async_timer(int64_t now)
        override
          { this->m_func(now);  }
      };

    // Allocate an abstract timer and insert it.
    auto timer = ::rocket::make_unique<Concrete_Timer>(next, period,
                                           ::std::forward<FuncT>(func));
    return Timer_Driver::insert(::std::move(timer));
  }

// Creates a one-shot timer. The timer is deleted after being triggered.
template<typename FuncT>
rcptr<Abstract_Timer>
create_async_timer_oneshot(int64_t next, FuncT&& func)
  {
    return noadl::create_async_timer(next, 0, ::std::forward<FuncT>(func));
  }

// Creates a periodic timer.
template<typename FuncT>
rcptr<Abstract_Timer>
create_async_timer_periodic(int64_t period, FuncT&& func)
  {
    return noadl::create_async_timer(period, period, ::std::forward<FuncT>(func));
  }

// Enqueues an asynchronous job and returns a future to its result.
// Functions with the same key will always be delivered to the same worker.
template<typename FuncT>
futp<typename ::std::result_of<FuncT ()>::type>
enqueue_async_job_keyed(uintptr_t key, FuncT&& func)
  {
    // // This is the concrete function class.
    struct Concrete_Async_Job : Abstract_Async_Job
      {
        prom<typename ::std::result_of<FuncT ()>::type> m_prom;
        typename ::std::decay<FuncT>::type m_func;

        explicit
        Concrete_Async_Job(uintptr_t key, FuncT&& func)
          : Abstract_Async_Job(key),
            m_func(::std::forward<FuncT>(func))
          { }

        void
        do_execute()
        override
          { this->m_prom.set_value(this->m_func());  }

        void
        do_set_exception(const ::std::exception_ptr& eptr)
        override
          { this->m_prom.set_exception(eptr);  }
      };

    // Allocate a function object.
    auto async = ::rocket::make_unique<Concrete_Async_Job>(key,
                                           ::std::forward<FuncT>(func));
    auto futr = async->m_prom.future();
    Worker_Pool::insert(::std::move(async));
    return futr;
  }

// Enqueues an asynchronous job and returns a future to its result.
// The function is delivered to a random worker.
template<typename FuncT>
futp<typename ::std::result_of<FuncT ()>::type>
enqueue_async_job_random(FuncT&& func)
  {
    // // This is the concrete function class.
    struct Concrete_Async_Job : Abstract_Async_Job
      {
        prom<typename ::std::result_of<FuncT ()>::type> m_prom;
        typename ::std::decay<FuncT>::type m_func;

        explicit
        Concrete_Async_Job(FuncT&& func)
          : Abstract_Async_Job(reinterpret_cast<uintptr_t>(this)),
            m_func(::std::forward<FuncT>(func))
          { }

        void
        do_execute()
        override
          { this->m_prom.set_value(this->m_func());  }

        void
        do_set_exception(const ::std::exception_ptr& eptr)
        override
          { this->m_prom.set_exception(eptr);  }
      };

    // Allocate a function object.
    auto async = ::rocket::make_unique<Concrete_Async_Job>(
                                           ::std::forward<FuncT>(func));
    auto futr = async->m_prom.future();
    Worker_Pool::insert(::std::move(async));
    return futr;
  }

}  // namespace asteria

#endif
<|endoftext|>


<commit_before>#include "messages.h"

Messages::Messages(peer *peerToConnect, QObject *parent) : QObject(parent), mPeer(peerToConnect)
{
    //here we create peerconnection session
}

Messages::~Messages()
{

}

Messages::ArmaMessage Messages::createRegularMessage(Session & session, const QString & message) {
	ArmaMessage ret;
	SessionKey & key = session.getKey();

	ret.append(session.getMyName().toUtf8().toBase64());
	ret.append(Messages::armaSeparator);
	ret.append(session.getPartnerName().toUtf8().toBase64());
	ret.append(Messages::armaSeparator);
	ret.append(QString::number(QDateTime::currentMSecsSinceEpoch()));
	ret.append(Messages::armaSeparator);

	if (!key.isMyDHCreated()) {
		ret.append('A' + Messages::RegularMessageDH);
		ret.append(Messages::armaSeparator);
		ret.append(key.getDH().toBase64());
	}
	else {
		ret.append('A' + Messages::RegularMessage);
	}
	ret.append(Messages::armaSeparator);

	ret.append(key.protect(message.toUtf8(), ret));

	key.generateKey();
	return ret;
}

Messages::ArmaMessage Messages::createLoginMessage(QString & name, const QString & password) {
	ArmaMessage ret;
	ret.append(name.toUtf8());
	ret.append(password.toUtf8().toBase64());
	return ret;
}

bool Messages::parseMessage(Session &session, ArmaMessage &message, Messages::ReceivedMessage &parsedMessage) {
	QByteArray senderNick, receiverNick, dh;
	QDateTime timestamp;
	char type;

	QList<QByteArray> list = message.split(armaSeparator);

	if (list.size() < 5) throw new MessageException("incomplete message");
	//senderNick = list[0];
	//receiverNick = list[1];

	timestamp.setMSecsSinceEpoch(list[2].toLongLong());
	parsedMessage.timestamp = timestamp;

	type = list[3][0] - 'A';

	QByteArray messageText;
	QByteArray encryptedData;

	//regularMessage
	if (type == RegularMessage) {

		//in case of separator occurence in data
		encryptedData.append(list[4]);
		for (int i = 5; i < list.size(); i++) {
			encryptedData.append(armaSeparator);
			encryptedData.append(list[i]);
		}

		SessionKey& sk = session.getKey();
		int contextDataLength = list[0].size() + list[1].size() + list[2].size() + list[3].size() + 4; //number of separators
		try{
			messageText = sk.unprotect(encryptedData, message.left(contextDataLength));
		}
		catch (KryptoException e) {
			return false;
		}
		parsedMessage.messageText = messageText;
	}

	//regularMessageDH
	if (type == RegularMessageDH) {
		if (list.size() < 6) throw new MessageException("incomplete message");
		dh = QByteArray::fromBase64(list[4]);

		//in case of separator occurence in data
		encryptedData.append(list[5]);
		for (int i = 6; i < list.size(); i++) {
			encryptedData.append(armaSeparator);
			encryptedData.append(list[i]);
		}

		SessionKey& sk = session.getKey();

		int contextDataLength = list[0].size() + list[1].size() + list[2].size() + list[3].size() + list[4].size() + 5;
		QByteArray messageText;
		try {
			messageText = sk.unprotect(encryptedData, message.left(contextDataLength));
		}
		catch (KryptoException e) {
			return false;
		}
		sk.setDH(dh);
		parsedMessage.messageText = messageText;
	}

	//fileTypes

	return true;
}
<commit_msg>Little something in message parsing (should lead to optimalization)<commit_after>#include "messages.h"

Messages::Messages(peer *peerToConnect, QObject *parent) : QObject(parent), mPeer(peerToConnect)
{
    //here we create peerconnection session
}

Messages::~Messages()
{

}

Messages::ArmaMessage Messages::createRegularMessage(Session & session, const QString & message) {
	ArmaMessage ret;
	SessionKey & key = session.getKey();

	ret.append(session.getMyName().toUtf8().toBase64());
	ret.append(Messages::armaSeparator);
	ret.append(session.getPartnerName().toUtf8().toBase64());
	ret.append(Messages::armaSeparator);
	ret.append(QString::number(QDateTime::currentMSecsSinceEpoch()));
	ret.append(Messages::armaSeparator);

	if (!key.isMyDHCreated()) {
		ret.append('A' + Messages::RegularMessageDH);
		ret.append(Messages::armaSeparator);
		ret.append(key.getDH().toBase64());
	}
	else {
		ret.append('A' + Messages::RegularMessage);
	}
	ret.append(Messages::armaSeparator);

	ret.append(key.protect(message.toUtf8(), ret));

	key.generateKey();
	return ret;
}

Messages::ArmaMessage Messages::createLoginMessage(QString & name, const QString & password) {
	ArmaMessage ret;
	ret.append(name.toUtf8());
	ret.append(password.toUtf8().toBase64());
	return ret;
}

bool Messages::parseMessage(Session &session, ArmaMessage &message, Messages::ReceivedMessage &parsedMessage) {
	QByteArray senderNick, receiverNick, dh;
	QDateTime timestamp;
	char type;

	QList<QByteArray> list = message.split(armaSeparator);

	if (list.size() < 5) throw new MessageException("incomplete message");
	//senderNick = list[0];
	//receiverNick = list[1];

	timestamp.setMSecsSinceEpoch(list[2].toLongLong());
	parsedMessage.timestamp = timestamp;

	type = list[3][0] - 'A';

	QByteArray messageText;
	QByteArray encryptedData;

	//regularMessage
	if (type == RegularMessage) {

		//in case of separator occurence in data
		encryptedData.append(list[4]);
		for (int i = 5; i < list.size(); i++) {
			encryptedData.append(armaSeparator);
			encryptedData.append(list[i]);
		}

		SessionKey& sk = session.getKey();
		int contextDataLength = list[0].size() + list[1].size() + list[2].size() + list[3].size() + 4; //number of separators
		try{
			messageText = sk.unprotect(encryptedData, message.left(contextDataLength));
		}
		catch (KryptoException e) {
			return false;
		}
		parsedMessage.messageText = messageText;
	}

	//regularMessageDH
	if (type == RegularMessageDH) {
		if (list.size() < 6) throw new MessageException("incomplete message");
		dh = QByteArray::fromBase64(list[4]);

		//in case of separator occurence in data
		encryptedData.append(list[5]);
		for (int i = 6; i < list.size(); i++) {
			encryptedData.append(armaSeparator);
			encryptedData.append(list[i]);
		}

		SessionKey& sk = session.getKey();

		int contextDataLength = list[0].size() + list[1].size() + list[2].size() + list[3].size() + list[4].size() + 5;
		QByteArray messageText;
		try {
			QByteArray a1 = message.left(contextDataLength);
			QByteArray a2 = message.right(message.length() - contextDataLength);
			messageText = sk.unprotect(a2, a1);
		}
		catch (KryptoException e) {
			return false;
		}
		sk.setDH(dh);
		parsedMessage.messageText = messageText;
	}

	//fileTypes

	return true;
}
<|endoftext|>


<commit_before>#include <iostream>

using namespace std;

int foo(int & a) {
    a += 2;
    return a - 2;
}

void bar(int a, int b) {
    a += foo(b);
    b += foo(a);
}

int main() {
    int x = 1, y = 2;

    cout << x << y << endl;

    return 0;
}
<commit_msg>Forgot to call bar in reference-params p4<commit_after>#include <iostream>

using namespace std;

int foo(int & a) {
    a += 2;
    return a - 2;
}

void bar(int a, int b) {
    a += foo(b);
    b += foo(a);
}

int main() {
    int x = 1, y = 2;

    bar(x, y);

    cout << x << y << endl;

    return 0;
}
<|endoftext|>


<commit_before>#include <signal.h>
#include <assert.h>

#include <algorithm>

#include <ep.hh>
#include <item.hh>

extern "C" {
    static rel_time_t basic_current_time(void) {
        return 0;
    }

    rel_time_t (*ep_current_time)() = basic_current_time;
}

class Counter : public HashTableVisitor {
public:

    int count;

    Counter() : count() {}

    void visit(StoredValue *v) {
        count += 1;
        std::string key = v->getKey();
        value_t val = v->getValue();
        assert(key.compare(*val) == 0);
    }
};

static int count(HashTable &h) {
    Counter c;
    h.visit(c);
    return c.count;
}

static void store(HashTable &h, std::string &k) {
    Item i(k, 0, 0, k.c_str(), k.length());
    h.set(i);
}

static void storeMany(HashTable &h, std::vector<std::string> &keys) {
    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        store(h, key);
    }
}

static void addMany(HashTable &h, std::vector<std::string> &keys, bool expect) {
    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string k = *it;
        Item i(k, 0, 0, k.c_str(), k.length());
        bool v = h.add(i);
        assert(expect == v);
    }
}

static std::vector<std::string> generateKeys(int num, int start=0) {
    std::vector<std::string> rv;

    for (int i = start; i < num; i++) {
        char buf[64];
        snprintf(buf, sizeof(buf), "key%d", i);
        std::string key(buf);
        rv.push_back(key);
    }

    return rv;
}

// ----------------------------------------------------------------------
// Actual tests below.
// ----------------------------------------------------------------------

static void testHashSize() {
    HashTable h;
    assert(count(h) == 0);

    std::string k = "testkey";
    store(h, k);

    assert(count(h) == 1);
}

static void testHashSizeTwo() {
    HashTable h;
    assert(count(h) == 0);

    std::vector<std::string> keys = generateKeys(5);
    storeMany(h, keys);
    assert(count(h) == 5);

    h.clear();
    assert(count(h) == 0);
}

static void testReverseDeletions() {
    alarm(10);
    HashTable h(5, 1);
    assert(count(h) == 0);
    const int nkeys = 10000;

    std::vector<std::string> keys = generateKeys(nkeys);
    storeMany(h, keys);
    assert(count(h) == nkeys);

    std::reverse(keys.begin(), keys.end());

    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        h.del(key);
    }

    assert(count(h) == 0);
}

static void testForwardDeletions() {
    alarm(10);
    HashTable h(5, 1);
    assert(h.getSize() == 5);
    assert(h.getNumLocks() == 1);
    assert(count(h) == 0);
    const int nkeys = 10000;

    std::vector<std::string> keys = generateKeys(nkeys);
    storeMany(h, keys);
    assert(count(h) == nkeys);

    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        h.del(key);
    }

    assert(count(h) == 0);
}

static void testFind() {
    HashTable h(5, 1);
    const int nkeys = 5000;

    std::vector<std::string> keys = generateKeys(nkeys);
    storeMany(h, keys);

    std::string missingKey = "aMissingKey";
    assert(h.find(missingKey) == NULL);

    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        assert(h.find(key));
    }
}

static void testAdd() {
    HashTable h(5, 1);
    const int nkeys = 5000;

    std::vector<std::string> keys = generateKeys(nkeys);
    addMany(h, keys, true);

    std::string missingKey = "aMissingKey";
    assert(h.find(missingKey) == NULL);

    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        assert(h.find(key));
    }

    addMany(h, keys, false);
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        assert(h.find(key));
    }
}

static void testDepthCounting() {
    HashTable h(5, 1);
    const int nkeys = 5000;

    std::vector<std::string> keys = generateKeys(nkeys);
    storeMany(h, keys);

    HashTableDepthStatVisitor depthCounter;
    h.visitDepth(depthCounter);
    // std::cout << "Max depth:  " << depthCounter.maxDepth << std::endl;
    assert(depthCounter.max > 1000);
}

int main() {
    testHashSize();
    testHashSizeTwo();
    testReverseDeletions();
    testForwardDeletions();
    testFind();
    testAdd();
    testDepthCounting();
    exit(0);
}
<commit_msg>Run hash table test with both regular and small StoredValues.<commit_after>#include <signal.h>
#include <assert.h>

#include <algorithm>

#include <ep.hh>
#include <item.hh>

extern "C" {
    static rel_time_t basic_current_time(void) {
        return 0;
    }

    rel_time_t (*ep_current_time)() = basic_current_time;
}

class Counter : public HashTableVisitor {
public:

    int count;

    Counter() : count() {}

    void visit(StoredValue *v) {
        count += 1;
        std::string key = v->getKey();
        value_t val = v->getValue();
        assert(key.compare(*val) == 0);
    }
};

static int count(HashTable &h) {
    Counter c;
    h.visit(c);
    return c.count;
}

static void store(HashTable &h, std::string &k) {
    Item i(k, 0, 0, k.c_str(), k.length());
    h.set(i);
}

static void storeMany(HashTable &h, std::vector<std::string> &keys) {
    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        store(h, key);
    }
}

static void addMany(HashTable &h, std::vector<std::string> &keys, bool expect) {
    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string k = *it;
        Item i(k, 0, 0, k.c_str(), k.length());
        bool v = h.add(i);
        assert(expect == v);
    }
}

static std::vector<std::string> generateKeys(int num, int start=0) {
    std::vector<std::string> rv;

    for (int i = start; i < num; i++) {
        char buf[64];
        snprintf(buf, sizeof(buf), "key%d", i);
        std::string key(buf);
        rv.push_back(key);
    }

    return rv;
}

// ----------------------------------------------------------------------
// Actual tests below.
// ----------------------------------------------------------------------

static void testHashSize() {
    HashTable h;
    assert(count(h) == 0);

    std::string k = "testkey";
    store(h, k);

    assert(count(h) == 1);
}

static void testHashSizeTwo() {
    HashTable h;
    assert(count(h) == 0);

    std::vector<std::string> keys = generateKeys(5);
    storeMany(h, keys);
    assert(count(h) == 5);

    h.clear();
    assert(count(h) == 0);
}

static void testReverseDeletions() {
    alarm(10);
    HashTable h(5, 1);
    assert(count(h) == 0);
    const int nkeys = 10000;

    std::vector<std::string> keys = generateKeys(nkeys);
    storeMany(h, keys);
    assert(count(h) == nkeys);

    std::reverse(keys.begin(), keys.end());

    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        h.del(key);
    }

    assert(count(h) == 0);
}

static void testForwardDeletions() {
    alarm(10);
    HashTable h(5, 1);
    assert(h.getSize() == 5);
    assert(h.getNumLocks() == 1);
    assert(count(h) == 0);
    const int nkeys = 10000;

    std::vector<std::string> keys = generateKeys(nkeys);
    storeMany(h, keys);
    assert(count(h) == nkeys);

    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        h.del(key);
    }

    assert(count(h) == 0);
}

static void testFind(HashTable &h) {
    const int nkeys = 5000;

    std::vector<std::string> keys = generateKeys(nkeys);
    storeMany(h, keys);

    std::string missingKey = "aMissingKey";
    assert(h.find(missingKey) == NULL);

    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        assert(h.find(key));
    }
}

static void testFind() {
    HashTable h(5, 1);
    testFind(h);
}

static void testFindSmall() {
    HashTable h(5, 1, small);
    testFind(h);
}

static void testAdd() {
    HashTable h(5, 1);
    const int nkeys = 5000;

    std::vector<std::string> keys = generateKeys(nkeys);
    addMany(h, keys, true);

    std::string missingKey = "aMissingKey";
    assert(h.find(missingKey) == NULL);

    std::vector<std::string>::iterator it;
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        assert(h.find(key));
    }

    addMany(h, keys, false);
    for (it = keys.begin(); it != keys.end(); it++) {
        std::string key = *it;
        assert(h.find(key));
    }
}

static void testDepthCounting() {
    HashTable h(5, 1);
    const int nkeys = 5000;

    std::vector<std::string> keys = generateKeys(nkeys);
    storeMany(h, keys);

    HashTableDepthStatVisitor depthCounter;
    h.visitDepth(depthCounter);
    // std::cout << "Max depth:  " << depthCounter.maxDepth << std::endl;
    assert(depthCounter.max > 1000);
}

int main() {
    testHashSize();
    testHashSizeTwo();
    testReverseDeletions();
    testForwardDeletions();
    testFind();
    testFindSmall();
    testAdd();
    testDepthCounting();
    exit(0);
}
<|endoftext|>