<commit_before>#ifndef _PITO_INTERCEPTOR_LIB_C_
#define _PITO_INTERCEPTOR_LIB_C_

#include <pito/interceptor/lib/c_traits.hpp>
#include <pito/interceptor/SystemCall.hpp>

#include <sys/types.h>
#include <sys/time.h>
#include <dirent.h>

#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>

#include "config.hpp"

#ifndef PITO_SYSTEM_CALL_BASE
#define PITO_SYSTEM_CALL_BASE  SystemCallBase
#endif

#ifndef PITO_JAIL_BASE
#define PITO_JAIL_BASE PITO_SYSTEM_CALL_BASE
#endif

namespace pito { namespace interceptor {

using namespace system_call;

template <>
struct Library<library::c> : LibraryHelper {
    Library() : LibraryHelper("libc.so") {}
};

#define PITO_ARGS(idx) type::at<idx, arg_types>::type arg##idx
#define PITO_ARGS_1    PITO_ARGS(0)
#define PITO_ARGS_2    PITO_ARGS(0), PITO_ARGS(1)
#define PITO_ARGS_3    PITO_ARGS(0), PITO_ARGS(1), PITO_ARGS(2)
#define PITO_ARGS_4    PITO_ARGS(0), PITO_ARGS(1), PITO_ARGS(2), PITO_ARGS(3)
#define PITO_ARGS_5    PITO_ARGS(0), PITO_ARGS(1), PITO_ARGS(2), PITO_ARGS(3), PITO_ARGS(4)

#define PITO_SYSTEM_CALL_WITH_BASE(_name, _library, _retVal, _argTypes, _argVals, _argTypeVals, _base) \
    template <> \
    struct SystemCall<_name> \
      : _base <_name, library::_library, _retVal _argTypes> {}; \
    extern "C" { \
        _retVal _name _argTypeVals { \
            return PITO_SUPER(_name) _argVals; \
        } \
    }

#define PITO_SYSTEM_CALL(_name, _library, _retVal, _argTypes, _argVals, _argTypeVals) \
    PITO_SYSTEM_CALL_WITH_BASE(_name, _library, _retVal, _argTypes, _argVals, _argTypeVals, PITO_SYSTEM_CALL_BASE)

////////////////////////////////////////////////////////////////////////////////
// security intercepts
PITO_SYSTEM_CALL(chmod, c, int, (const char *, mode_t), \
                 (path, mode), \
                 (char const *path, mode_t mode))
PITO_SYSTEM_CALL(fchmod, c, int, (int, mode_t), \
                 (fd, mode), \
                 (int fd, mode_t mode))
PITO_SYSTEM_CALL(fchmodat, c, int, (int, const char *, mode_t, int), \
                 (dirfd, path, mode, flags), \
                 (int dirfd, char const *path, mode_t mode, int flags))
PITO_SYSTEM_CALL(chown, c, int, (const char *, uid_t, gid_t), \
                 (path, owner, group), \
                 (const char *path, uid_t owner, gid_t group))
PITO_SYSTEM_CALL(fchown, c, int, (int, uid_t, gid_t), \
                 (fd, owner, group), \
                 (int fd, uid_t owner, gid_t group))
PITO_SYSTEM_CALL(fchownat, c, int, (int, const char *, uid_t, gid_t, int), \
                 (dirfd, pathname, owner, group, flags), \
                 (int dirfd, const char *pathname, uid_t owner, gid_t group, int flags))

template <>
struct SystemCall<open>
  : PITO_SYSTEM_CALL_BASE<open, library::c, int(const char *, int)> {};

extern "C" {
    int open(const char *pathname, int flags, ...) {
        if (flags & O_CREAT) {
            va_list ap;
            va_start(ap, flags);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(open)(pathname, flags, mode);
        }
        else return PITO_SUPER(open)(pathname, flags);
    }
}

template <>
struct SystemCall<openat>
  : PITO_SYSTEM_CALL_BASE<openat, library::c, int(int, const char *, int)> {};

extern "C" {
    int openat(int dirfd, const char *pathname, int flags, ...) {
        if (flags & O_CREAT) {
            va_list ap;
            va_start(ap, flags);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(openat)(dirfd, pathname, flags, mode);
        }
        else return PITO_SUPER(openat)(dirfd, pathname, flags);
    }
}

PITO_SYSTEM_CALL(creat, c, int, (const char *, mode_t), \
                 (pathname, mode), \
                 (const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(fopen, c, FILE *, (const char *, const char *), \
                 (path, mode), \
                 (const char *path, const char *mode))
PITO_SYSTEM_CALL(lchown, c, int, (const char *, uid_t, gid_t), \
                 (path, owner, group), \
                 (const char *path, uid_t owner, gid_t group))
PITO_SYSTEM_CALL(link, c, int, (const char *, const char *), \
                 (oldpath, newpath), \
                 (const char *oldpath, const char *newpath))
PITO_SYSTEM_CALL(linkat, c, int, (int, const char *, int, const char *, int), \
                 (olddirfd, oldpath, newdirfd, newpath, flags), \
                 (int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags))
PITO_SYSTEM_CALL(mkdir, c, int, (const char *, mode_t), \
                 (pathname, mode), \
                 (const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(mkdirat, c, int, (int, const char *, mode_t), \
                 (dirfd, pathname, mode), \
                 (int dirfd, const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(opendir, c, DIR *, (const char *), \
                 (name), \
                 (const char *name))
PITO_SYSTEM_CALL(mknod, c, int, (const char *, mode_t, dev_t), \
                 (pathname, mode, dev), \
                 (const char *pathname, mode_t mode, dev_t dev))
PITO_SYSTEM_CALL(mknodat, c, int, (int, const char *, mode_t, dev_t), \
                 (dirfd, pathname, mode, dev), \
                 (int dirfd, const char *pathname, mode_t mode, dev_t dev))
// function todo: __xmknod
PITO_SYSTEM_CALL(mkfifo, c, int, (const char *, mode_t), \
                 (pathname, mode), \
                 (const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(mkfifoat, c, int, (int, const char *, mode_t), \
                 (dirfd, pathname, mode), \
                 (int dirfd, const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(access, c, int, (const char *, int), \
                 (pathname, mode), \
                 (const char *pathname, int mode))
PITO_SYSTEM_CALL(faccessat, c, int, (int, const char *, int, int), \
                 (dirfd, pathname, mode, flags), \
                 (int dirfd, const char *pathname, int mode, int flags))
PITO_SYSTEM_CALL(rename, c, int, (const char *, const char *), \
                 (oldpath, newpath), \
                 (const char *oldpath, const char *newpath))
PITO_SYSTEM_CALL(renameat, c, int, (int, const char *, int, const char *), \
                 (olddirfd, oldpath, newdirfd, newpath), \
                 (int olddirfd, const char *oldpath, int newdirfd, const char *newpath))
PITO_SYSTEM_CALL(rmdir, c, int, (const char *), \
                 (pathname), \
                 (const char *pathname))
PITO_SYSTEM_CALL(symlink, c, int, (const char *, const char *), \
                 (oldpath, newpath), \
                 (const char *oldpath, const char *newpath))
PITO_SYSTEM_CALL(symlinkat, c, int, (const char *, int, const char *), \
                 (oldpath, newdirfd, newpath), \
                 (const char *oldpath, int newdirfd, const char *newpath))
PITO_SYSTEM_CALL(truncate, c, int, (const char *, off_t), \
                 (path, length), \
                 (const char *path, off_t length))
PITO_SYSTEM_CALL(unlink, c, int, (const char *), \
                 (pathname), \
                 (const char *pathname))
PITO_SYSTEM_CALL(unlinkat, c, int, (int, const char *, int), \
                 (dirfd, pathname, flags), \
                 (int dirfd, const char *pathname, int flags))
PITO_SYSTEM_CALL(getcwd, c, char *, (char *, size_t), \
                 (buf, size), \
                 (char *buf, size_t size))

template <>
struct SystemCall<open64>
  : PITO_SYSTEM_CALL_BASE<open64, library::c, int(const char *, int)> {};

extern "C" {
    int open64(const char *pathname, int flags, ...) {
        if (flags & O_CREAT) {
            va_list ap;
            va_start(ap, flags);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(open64)(pathname, flags, mode);
        }
        else return PITO_SUPER(open64)(pathname, flags);
    }
}

template <>
struct SystemCall<openat64>
  : PITO_SYSTEM_CALL_BASE<openat64, library::c, int(int, const char *, int)> {};

extern "C" {
    typedef SystemCall<openat64>::arg_types arg_types;
    int openat64(PITO_ARGS_3, ...) {
        if (arg2 & O_CREAT) {
            va_list ap;
            va_start(ap, arg2);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(openat64)(arg0, arg1, arg2, mode);
        }
        else return PITO_SUPER(openat64)(arg0, arg1, arg2);
    }
}

PITO_SYSTEM_CALL(creat64, c, int, (const char *, mode_t), \
                 (pathname, mode), \
                 (const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(fopen64, c, FILE *, (const char *, const char *), \
                 (path, mode), \
                 (const char *path, const char *mode))
PITO_SYSTEM_CALL(truncate64, c, int, (const char *, PITO_OFF64_TYPE), \
                 (path, length), \
                 (const char *path, PITO_OFF64_TYPE length))

////////////////////////////////////////////////////////////////////////////////
// jail
////////////////////////////////////////////////////////////////////////////////
PITO_SYSTEM_CALL_WITH_BASE(execve, c, int, (const char *, char *const[], char *const[]), \
                           (filename, argv, envp), \
                           (const char *filename, char *const argv[], char *const envp[]), \
                           PITO_JAIL_BASE)
PITO_SYSTEM_CALL_WITH_BASE(execv, c, int, (const char *, char *const[]), \
                           (filename, argv), \
                           (const char *filename, char *const argv[]), \
                           PITO_JAIL_BASE)
PITO_SYSTEM_CALL_WITH_BASE(execvp, c, int, (const char *, char *const[]), \
                           (filename, argv), \
                           (const char *filename, char *const argv[]), \
                           PITO_JAIL_BASE)
////////////////////////////////////////////////////////////////////////////////
// end jail
////////////////////////////////////////////////////////////////////////////////

PITO_SYSTEM_CALL(utime, c, int, (const char *, const struct utimbuf *), \
                 (filename, times), \
                 (const char *filename, const struct utimbuf *times))
PITO_SYSTEM_CALL(utimes, c, int, (const char *, const struct timeval[2]), \
                 (filename, times), \
                 (const char *filename, const struct timeval times[2]))
PITO_SYSTEM_CALL(utimensat, c, int, (int, const char *, const struct timespec[2], int), \
                 (dirfd, pathname, times, flags), \
                 (int dirfd, const char *pathname, const struct timespec times[2], int flags))
PITO_SYSTEM_CALL(futimesat, c, int, (int, const char *, const struct timeval[2]), \
                 (dirfd, pathname, times), \
                 (int dirfd, const char *pathname, const struct timeval times[2]))
PITO_SYSTEM_CALL(lutimes, c, int, (const char *, const struct timeval[2]), \
                 (filename, tv), \
                 (const char *filename, const struct timeval tv[2]))
PITO_SYSTEM_CALL(getuid, c, int, (void), (), ())

} }

#endif
<commit_msg>make it more flexible, oh<commit_after>#ifndef _PITO_INTERCEPTOR_LIB_C_
#define _PITO_INTERCEPTOR_LIB_C_

#include <pito/interceptor/lib/c_traits.hpp>
#include <pito/interceptor/SystemCall.hpp>

#include <sys/types.h>
#include <sys/time.h>
#include <dirent.h>

#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>

#include "config.hpp"

#ifndef PITO_SYSTEM_CALL_BASE
#define PITO_SYSTEM_CALL_BASE  SystemCallBase
#endif

#ifndef PITO_JAIL_BASE
#define PITO_JAIL_BASE PITO_SYSTEM_CALL_BASE
#endif

namespace pito { namespace interceptor {

using namespace system_call;

template <>
struct Library<library::c> : LibraryHelper {
    Library() : LibraryHelper("libc.so") {}
};

#define PITO_ARG_NAME(idx) arg##idx
#define PITO_ARG_NAMES_1(idx)   PITO_ARG_NAME(0)
#define PITO_ARG_NAMES_2(idx)   PITO_ARG_NAME_1, PITO_ARG_NAME(1)
#define PITO_ARG_NAMES_3(idx)   PITO_ARG_NAME_2, PITO_ARG_NAME(2)
#define PITO_ARG_NAMES_4(idx)   PITO_ARG_NAME_3, PITO_ARG_NAME(3)
#define PITO_ARG_NAMES_5(idx)   PITO_ARG_NAME_4, PITO_ARG_NAME(4)

#define PITO_ARG(idx, list) type::at<idx, list>::type PITO_ARG_NAME(idx)
#define PITO_ARGS_1(list)   PITO_ARG(0, list)
#define PITO_ARGS_2(list)   PITO_ARGS_1(list), PITO_ARG(1, list)
#define PITO_ARGS_3(list)   PITO_ARGS_2(list), PITO_ARG(2, list)
#define PITO_ARGS_4(list)   PITO_ARGS_3(list), PITO_ARG(3, list)
#define PITO_ARGS_5(list)   PITO_ARGS_4(list), PITO_ARG(4, list)

#define PITO_SYSTEM_CALL_WITH_BASE(_name, _library, _retVal, _argTypes, _argVals, _argTypeVals, _base) \
    template <> \
    struct SystemCall<_name> \
      : _base <_name, library::_library, _retVal _argTypes> {}; \
    extern "C" { \
        _retVal _name _argTypeVals { \
            return PITO_SUPER(_name) _argVals; \
        } \
    }

#define PITO_SYSTEM_CALL(_name, _library, _retVal, _argTypes, _argVals, _argTypeVals) \
    PITO_SYSTEM_CALL_WITH_BASE(_name, _library, _retVal, _argTypes, _argVals, _argTypeVals, PITO_SYSTEM_CALL_BASE)

////////////////////////////////////////////////////////////////////////////////
// security intercepts
PITO_SYSTEM_CALL(chmod, c, int, (const char *, mode_t), \
                 (path, mode), \
                 (char const *path, mode_t mode))
PITO_SYSTEM_CALL(fchmod, c, int, (int, mode_t), \
                 (fd, mode), \
                 (int fd, mode_t mode))
PITO_SYSTEM_CALL(fchmodat, c, int, (int, const char *, mode_t, int), \
                 (dirfd, path, mode, flags), \
                 (int dirfd, char const *path, mode_t mode, int flags))
PITO_SYSTEM_CALL(chown, c, int, (const char *, uid_t, gid_t), \
                 (path, owner, group), \
                 (const char *path, uid_t owner, gid_t group))
PITO_SYSTEM_CALL(fchown, c, int, (int, uid_t, gid_t), \
                 (fd, owner, group), \
                 (int fd, uid_t owner, gid_t group))
PITO_SYSTEM_CALL(fchownat, c, int, (int, const char *, uid_t, gid_t, int), \
                 (dirfd, pathname, owner, group, flags), \
                 (int dirfd, const char *pathname, uid_t owner, gid_t group, int flags))

template <>
struct SystemCall<open>
  : PITO_SYSTEM_CALL_BASE<open, library::c, int(const char *, int)> {};

extern "C" {
    int open(const char *pathname, int flags, ...) {
        if (flags & O_CREAT) {
            va_list ap;
            va_start(ap, flags);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(open)(pathname, flags, mode);
        }
        else return PITO_SUPER(open)(pathname, flags);
    }
}

template <>
struct SystemCall<openat>
  : PITO_SYSTEM_CALL_BASE<openat, library::c, int(int, const char *, int)> {};

extern "C" {
    int openat(int dirfd, const char *pathname, int flags, ...) {
        if (flags & O_CREAT) {
            va_list ap;
            va_start(ap, flags);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(openat)(dirfd, pathname, flags, mode);
        }
        else return PITO_SUPER(openat)(dirfd, pathname, flags);
    }
}

PITO_SYSTEM_CALL(creat, c, int, (const char *, mode_t), \
                 (pathname, mode), \
                 (const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(fopen, c, FILE *, (const char *, const char *), \
                 (path, mode), \
                 (const char *path, const char *mode))
PITO_SYSTEM_CALL(lchown, c, int, (const char *, uid_t, gid_t), \
                 (path, owner, group), \
                 (const char *path, uid_t owner, gid_t group))
PITO_SYSTEM_CALL(link, c, int, (const char *, const char *), \
                 (oldpath, newpath), \
                 (const char *oldpath, const char *newpath))
PITO_SYSTEM_CALL(linkat, c, int, (int, const char *, int, const char *, int), \
                 (olddirfd, oldpath, newdirfd, newpath, flags), \
                 (int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags))
PITO_SYSTEM_CALL(mkdir, c, int, (const char *, mode_t), \
                 (pathname, mode), \
                 (const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(mkdirat, c, int, (int, const char *, mode_t), \
                 (dirfd, pathname, mode), \
                 (int dirfd, const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(opendir, c, DIR *, (const char *), \
                 (name), \
                 (const char *name))
PITO_SYSTEM_CALL(mknod, c, int, (const char *, mode_t, dev_t), \
                 (pathname, mode, dev), \
                 (const char *pathname, mode_t mode, dev_t dev))
PITO_SYSTEM_CALL(mknodat, c, int, (int, const char *, mode_t, dev_t), \
                 (dirfd, pathname, mode, dev), \
                 (int dirfd, const char *pathname, mode_t mode, dev_t dev))
// function todo: __xmknod
PITO_SYSTEM_CALL(mkfifo, c, int, (const char *, mode_t), \
                 (pathname, mode), \
                 (const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(mkfifoat, c, int, (int, const char *, mode_t), \
                 (dirfd, pathname, mode), \
                 (int dirfd, const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(access, c, int, (const char *, int), \
                 (pathname, mode), \
                 (const char *pathname, int mode))
PITO_SYSTEM_CALL(faccessat, c, int, (int, const char *, int, int), \
                 (dirfd, pathname, mode, flags), \
                 (int dirfd, const char *pathname, int mode, int flags))
PITO_SYSTEM_CALL(rename, c, int, (const char *, const char *), \
                 (oldpath, newpath), \
                 (const char *oldpath, const char *newpath))
PITO_SYSTEM_CALL(renameat, c, int, (int, const char *, int, const char *), \
                 (olddirfd, oldpath, newdirfd, newpath), \
                 (int olddirfd, const char *oldpath, int newdirfd, const char *newpath))
PITO_SYSTEM_CALL(rmdir, c, int, (const char *), \
                 (pathname), \
                 (const char *pathname))
PITO_SYSTEM_CALL(symlink, c, int, (const char *, const char *), \
                 (oldpath, newpath), \
                 (const char *oldpath, const char *newpath))
PITO_SYSTEM_CALL(symlinkat, c, int, (const char *, int, const char *), \
                 (oldpath, newdirfd, newpath), \
                 (const char *oldpath, int newdirfd, const char *newpath))
PITO_SYSTEM_CALL(truncate, c, int, (const char *, off_t), \
                 (path, length), \
                 (const char *path, off_t length))
PITO_SYSTEM_CALL(unlink, c, int, (const char *), \
                 (pathname), \
                 (const char *pathname))
PITO_SYSTEM_CALL(unlinkat, c, int, (int, const char *, int), \
                 (dirfd, pathname, flags), \
                 (int dirfd, const char *pathname, int flags))
PITO_SYSTEM_CALL(getcwd, c, char *, (char *, size_t), \
                 (buf, size), \
                 (char *buf, size_t size))

template <>
struct SystemCall<open64>
  : PITO_SYSTEM_CALL_BASE<open64, library::c, int(const char *, int)> {};

extern "C" {
    int open64(const char *pathname, int flags, ...) {
        if (flags & O_CREAT) {
            va_list ap;
            va_start(ap, flags);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(open64)(pathname, flags, mode);
        }
        else return PITO_SUPER(open64)(pathname, flags);
    }
}

template <>
struct SystemCall<openat64>
  : PITO_SYSTEM_CALL_BASE<openat64, library::c, int(int, const char *, int)> {};

extern "C" {
    int openat64(PITO_ARGS_3(SystemCall<openat64>::arg_types), ...) {
        if (arg2 & O_CREAT) {
            va_list ap;
            va_start(ap, arg2);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(openat64)(arg0, arg1, arg2, mode);
        }
        else return PITO_SUPER(openat64)(arg0, arg1, arg2);
    }
}

PITO_SYSTEM_CALL(creat64, c, int, (const char *, mode_t), \
                 (pathname, mode), \
                 (const char *pathname, mode_t mode))
PITO_SYSTEM_CALL(fopen64, c, FILE *, (const char *, const char *), \
                 (path, mode), \
                 (const char *path, const char *mode))
PITO_SYSTEM_CALL(truncate64, c, int, (const char *, PITO_OFF64_TYPE), \
                 (path, length), \
                 (const char *path, PITO_OFF64_TYPE length))

////////////////////////////////////////////////////////////////////////////////
// jail
////////////////////////////////////////////////////////////////////////////////
PITO_SYSTEM_CALL_WITH_BASE(execve, c, int, (const char *, char *const[], char *const[]), \
                           (filename, argv, envp), \
                           (const char *filename, char *const argv[], char *const envp[]), \
                           PITO_JAIL_BASE)
PITO_SYSTEM_CALL_WITH_BASE(execv, c, int, (const char *, char *const[]), \
                           (filename, argv), \
                           (const char *filename, char *const argv[]), \
                           PITO_JAIL_BASE)
PITO_SYSTEM_CALL_WITH_BASE(execvp, c, int, (const char *, char *const[]), \
                           (filename, argv), \
                           (const char *filename, char *const argv[]), \
                           PITO_JAIL_BASE)
////////////////////////////////////////////////////////////////////////////////
// end jail
////////////////////////////////////////////////////////////////////////////////

PITO_SYSTEM_CALL(utime, c, int, (const char *, const struct utimbuf *), \
                 (filename, times), \
                 (const char *filename, const struct utimbuf *times))
PITO_SYSTEM_CALL(utimes, c, int, (const char *, const struct timeval[2]), \
                 (filename, times), \
                 (const char *filename, const struct timeval times[2]))
PITO_SYSTEM_CALL(utimensat, c, int, (int, const char *, const struct timespec[2], int), \
                 (dirfd, pathname, times, flags), \
                 (int dirfd, const char *pathname, const struct timespec times[2], int flags))
PITO_SYSTEM_CALL(futimesat, c, int, (int, const char *, const struct timeval[2]), \
                 (dirfd, pathname, times), \
                 (int dirfd, const char *pathname, const struct timeval times[2]))
PITO_SYSTEM_CALL(lutimes, c, int, (const char *, const struct timeval[2]), \
                 (filename, tv), \
                 (const char *filename, const struct timeval tv[2]))
PITO_SYSTEM_CALL(getuid, c, int, (void), (), ())

} }

#endif
<|endoftext|>


<commit_before>#include "PathShortener.h"
#include "simulation/World.h"
#include "RRT.h"
#include "collision/CollisionDetector.h"
#include "dynamics/Skeleton.h"

using namespace std;
using namespace Eigen;
using namespace dart;
using namespace simulation;

#define RAND12(N1,N2) N1 + ((N2-N1) * ((double)rand() / ((double)RAND_MAX + 1))) // random # between N&M

namespace dart {
namespace planning {

PathShortener::PathShortener() {}

PathShortener::PathShortener(World* world, dynamics::Skeleton* robot, const vector<int> &dofs, double stepSize) :
   world(world),
   robot(robot),
   dofs(dofs),
   stepSize(stepSize)
{}

PathShortener::~PathShortener()
{}

void PathShortener::shortenPath(list<VectorXd> &path)
{
	printf("--> Start Brute Force Shortener \n");
	srand(time(NULL));

	VectorXd savedDofs = robot->getConfig(dofs);

	const int numShortcuts = path.size() * 5;

	// Number of checks
	for( int count = 0; count < numShortcuts; count++ ) {
		if( path.size() < 3 ) { //-- No way we can reduce something leaving out the extremes
			return;
		}

		int node1Index;
		int node2Index;
		do {
			node1Index = (int) RAND12(0, path.size());
			node2Index = (int) RAND12(0, path.size());
		} while(node2Index <= node1Index + 1);

		list<VectorXd>::iterator node1Iter = path.begin();
		advance(node1Iter, node1Index);
		list<VectorXd>::iterator node2Iter = node1Iter;
		advance(node2Iter, node2Index - node1Index);

		list<VectorXd> intermediatePoints;
		if(localPlanner(intermediatePoints, node1Iter, node2Iter)) {
			list<VectorXd>::iterator node1NextIter = node1Iter;
			node1NextIter++;
			path.erase(node1NextIter, node2Iter);
			path.splice(node2Iter, intermediatePoints);
		}
	}
	robot->setConfig(dofs, savedDofs);

	printf("End Brute Force Shortener \n");
}

bool PathShortener::localPlanner(list<VectorXd> &intermediatePoints, list<VectorXd>::const_iterator it1, list<VectorXd>::const_iterator it2) {
	return segmentCollisionFree(intermediatePoints, *it1, *it2);
}

// true iff collision-free
// does not check endpoints
// interemdiatePoints are only touched if collision-free
bool PathShortener::segmentCollisionFree(list<VectorXd> &intermediatePoints, const VectorXd &config1, const VectorXd &config2) {
	const double length = (config1 - config2).norm();
	if(length <= stepSize) {
		return true;
	}

	const int n = (int)(length / stepSize) + 1; // number of intermediate segments
	int n1 = n / 2;
	int n2 = n / 2;
	if(n % 2 == 1) {
		n2 += 1;
	}

	VectorXd midpoint = (double)n2 / (double)n * config1 + (double)n1 / (double)n * config2;
	list<VectorXd> intermediatePoints1, intermediatePoints2;
	robot->setConfig(dofs, midpoint);
	if(!world->checkCollision() && segmentCollisionFree(intermediatePoints1, config1, midpoint)
			&& segmentCollisionFree(intermediatePoints2, midpoint, config2))
	{
		intermediatePoints.clear();
		intermediatePoints.splice(intermediatePoints.end(), intermediatePoints1);
		intermediatePoints.push_back(midpoint);
		intermediatePoints.splice(intermediatePoints.end(), intermediatePoints2);
		return true;
	}
	else {
		return false;
	}
}

} // namespace planning
} // namespace dart
<commit_msg>Fix compiler error on Windows<commit_after>#include "PathShortener.h"
#include "simulation/World.h"
#include "RRT.h"
#include "collision/CollisionDetector.h"
#include "dynamics/Skeleton.h"
#include <ctime>

using namespace std;
using namespace Eigen;
using namespace dart;
using namespace simulation;

#define RAND12(N1,N2) N1 + ((N2-N1) * ((double)rand() / ((double)RAND_MAX + 1))) // random # between N&M

namespace dart {
namespace planning {

PathShortener::PathShortener() {}

PathShortener::PathShortener(World* world, dynamics::Skeleton* robot, const vector<int> &dofs, double stepSize) :
   world(world),
   robot(robot),
   dofs(dofs),
   stepSize(stepSize)
{}

PathShortener::~PathShortener()
{}

void PathShortener::shortenPath(list<VectorXd> &path)
{
	printf("--> Start Brute Force Shortener \n");
	srand(time(NULL));

	VectorXd savedDofs = robot->getConfig(dofs);

	const int numShortcuts = path.size() * 5;

	// Number of checks
	for( int count = 0; count < numShortcuts; count++ ) {
		if( path.size() < 3 ) { //-- No way we can reduce something leaving out the extremes
			return;
		}

		int node1Index;
		int node2Index;
		do {
			node1Index = (int) RAND12(0, path.size());
			node2Index = (int) RAND12(0, path.size());
		} while(node2Index <= node1Index + 1);

		list<VectorXd>::iterator node1Iter = path.begin();
		advance(node1Iter, node1Index);
		list<VectorXd>::iterator node2Iter = node1Iter;
		advance(node2Iter, node2Index - node1Index);

		list<VectorXd> intermediatePoints;
		if(localPlanner(intermediatePoints, node1Iter, node2Iter)) {
			list<VectorXd>::iterator node1NextIter = node1Iter;
			node1NextIter++;
			path.erase(node1NextIter, node2Iter);
			path.splice(node2Iter, intermediatePoints);
		}
	}
	robot->setConfig(dofs, savedDofs);

	printf("End Brute Force Shortener \n");
}

bool PathShortener::localPlanner(list<VectorXd> &intermediatePoints, list<VectorXd>::const_iterator it1, list<VectorXd>::const_iterator it2) {
	return segmentCollisionFree(intermediatePoints, *it1, *it2);
}

// true iff collision-free
// does not check endpoints
// interemdiatePoints are only touched if collision-free
bool PathShortener::segmentCollisionFree(list<VectorXd> &intermediatePoints, const VectorXd &config1, const VectorXd &config2) {
	const double length = (config1 - config2).norm();
	if(length <= stepSize) {
		return true;
	}

	const int n = (int)(length / stepSize) + 1; // number of intermediate segments
	int n1 = n / 2;
	int n2 = n / 2;
	if(n % 2 == 1) {
		n2 += 1;
	}

	VectorXd midpoint = (double)n2 / (double)n * config1 + (double)n1 / (double)n * config2;
	list<VectorXd> intermediatePoints1, intermediatePoints2;
	robot->setConfig(dofs, midpoint);
	if(!world->checkCollision() && segmentCollisionFree(intermediatePoints1, config1, midpoint)
			&& segmentCollisionFree(intermediatePoints2, midpoint, config2))
	{
		intermediatePoints.clear();
		intermediatePoints.splice(intermediatePoints.end(), intermediatePoints1);
		intermediatePoints.push_back(midpoint);
		intermediatePoints.splice(intermediatePoints.end(), intermediatePoints2);
		return true;
	}
	else {
		return false;
	}
}

} // namespace planning
} // namespace dart
<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>

using namespace std;

template <class T>
class Tree
{
private:
	struct Node

	{
		T value_;
		Node *left;
		Node *right;
		Node() {};
		Node(const T value) : value_(value) { };
		~Node() {};
		void show(ostream &out, int level) const;
	};

	Node *root;
	void null_tree(Node *tr_)
	{
		if (!tr_) return;
		if (tr_->left)
		{
			null_tree(tr_->left);
			tr_->left = nullptr;
		}
		if (tr_->right)
		{
			null_tree(tr_->right);
			tr_->right = nullptr;
		}
		delete tr_;
	}
	Node *  find_(const T &value) const
	{

		Node *tr = root;
		while (tr)
		{
			if (tr->value_ != value)
			{
				if (value < tr->value_)
					tr = tr->left;
				else tr = tr->right;
			}
			else break;
		}
		if (!tr) return nullptr;
		else return tr;
	}
	void add_node(Node *&add_n, T value)
	{
		add_n = new Node(value);
		add_n->left = nullptr;
		add_n->right = nullptr;

	}
	Node* add_(const T &value, Node * tr = 0)
	{

		if (!root)
		{
			root = new Node(value);
			root->left = nullptr;
			root->right = nullptr;
			return root;
		}
		if (!tr) tr = root;
		if ((tr) && (tr->value_ != value))

		{
			if (value < tr->value_)

			{
				if (tr->left)
					add_(value, tr->left);
				else
				{
					add_node(tr->left, value);
					return tr->left;
				}
			}

			else
			{
				if (tr->right)
					add_(value, tr->right);
				else
				{
					add_node(tr->right, value);
					return tr->right;
				}
			}
		}
		return 0;
	}
	int count(Node* tr) const
	{
		if (!tr) return 0;
		int l = 0, r = 0;
		if (tr->left) l = count(tr->left);
		if (tr->right) r = count(tr->right);
		return l + r + 1;
	}
	void print_pre(const Node * tr, std::ofstream &file) const
	{
		try
		{
			if (!tr) throw 1;
		}
		catch (int)
		{
			return;
		}
		file << tr->value_ << "  ";
		if (tr->left)
			print_pre(tr->left, file);
		if (tr->right)
			print_pre(tr->right, file);
	}
	void Delete(Node **Tree, T &value)
	{
		Node *q;

		if (*Tree == nullptr) return;
		else
			if (value<(**Tree).value_) Delete(&((**Tree).left), value);
			else
				if (value>(**Tree).value_) Delete(&((**Tree).right), value);
				else {
					q = *Tree;
					if ((*q).right ==nullptr) { *Tree = (*q).left; delete q; }
					else
						if ((*q).left == nullptr) { *Tree = (*q).right; delete q; }
						else Delete_(&((*q).left), &q);
				}
	}
	void Delete_(Node **r, Node **q)
	{
		Node *s;

		if ((**r).right == nullptr)
		{
			(**q).value_ = (**r).value_; *q = *r;
			s = *r; *r = (**r).left; delete s;
		}
		else Delete_(&((**r).right), q);
	}

public:
	Tree()
	{
		root = nullptr;
	};
	~Tree()
	{
		null_tree(root);
	};
	Node* tree_one()
	{
		return root;
	};
	void file_tree(char* name);
	bool add(const T &value);
	bool find(const T &value);
	void print(ostream &out) const;
	int count_() const;
	bool del(T value)
	{
		try
		{
			if (find(value) == 0) throw 1;
		}
		catch (int i = 1)
		{
			return 0;
		}

		Delete(&root, value);
		return !find(value);
	}
	void pr(char* name) const;
};
void main()
{
	Tree<int>a;
	a.add(7);
	bool b=a.del(2);
	cout << b;
	system("pause");
}

template <class T>
void Tree<T>::pr(char* name) const
{
	ofstream file(name);
	if (file.is_open())
	{
		file << count_() << " ";
		print_pre(root, file);

		file.close();
	}
}
template <class T>
int Tree<T>::count_() const
{
	return count(root);
}
template <class T>
void  Tree<T>::print(ostream &out) const
{
	root->show(out, 0);
}
template <class T>
void Tree<T>::Node::show(ostream &out, int level) const
{
	const Node *tr = this;
	if (tr) tr->right->show(out, level + 1);
	for (int i = 0; i<level; i++)
		out << "   ";
	if (tr) out << tr->value_ << endl;
	else out << "End" << endl;
	if (tr) tr->left->show(out, level + 1);
}
template <class T>
bool Tree<T>::add(const T &value)
{
	Node *tr = add_(value);
	if (tr) return true;
	else    return false;
}
template <class T>
void Tree<T>::file_tree(char* name)
{
	ifstream file(name);
	try
	{
		if (file.is_open()==0) throw 1;
	}
	catch (int i = 1)
	{
		return 0;
	}

	if (file.is_open())
	{
		int i_max;
		file >> i_max;
		for (int i = 0; i < i_max; ++i)
		{
			T node;
			file >> node;
			add(node);
		}
		file.close();
	}
}
template <class T>
bool Tree<T>::find(const T &value)
{
	Node *tr = find_(value);
	if (tr) return true;
	else    return false;
}
<commit_msg>Update tree.hpp<commit_after>#include <fstream>
#include <iostream>

using namespace std;

template <class T>
class Tree
{
private:
	struct Node

	{
		T value_;
		Node *left;
		Node *right;
		Node() {};
		Node(const T value) : value_(value) { };
		~Node() {};
		void show(ostream &out, int level) const;
	};

	Node *root;
	void null_tree(Node *tr_)
	{
		if (!tr_) return;
		if (tr_->left)
		{
			null_tree(tr_->left);
			tr_->left = nullptr;
		}
		if (tr_->right)
		{
			null_tree(tr_->right);
			tr_->right = nullptr;
		}
		delete tr_;
	}
	Node *  find_(const T &value) const
	{

		Node *tr = root;
		while (tr)
		{
			if (tr->value_ != value)
			{
				if (value < tr->value_)
					tr = tr->left;
				else tr = tr->right;
			}
			else break;
		}
		if (!tr) return nullptr;
		else return tr;
	}
	void add_node(Node *&add_n, T value)
	{
		add_n = new Node(value);
		add_n->left = nullptr;
		add_n->right = nullptr;

	}
	Node* add_(const T &value, Node * tr = 0)
	{

		if (!root)
		{
			root = new Node(value);
			root->left = nullptr;
			root->right = nullptr;
			return root;
		}
		if (!tr) tr = root;
		if ((tr) && (tr->value_ != value))

		{
			if (value < tr->value_)

			{
				if (tr->left)
					add_(value, tr->left);
				else
				{
					add_node(tr->left, value);
					return tr->left;
				}
			}

			else
			{
				if (tr->right)
					add_(value, tr->right);
				else
				{
					add_node(tr->right, value);
					return tr->right;
				}
			}
		}
		return 0;
	}
	int count(Node* tr) const
	{
		if (!tr) return 0;
		int l = 0, r = 0;
		if (tr->left) l = count(tr->left);
		if (tr->right) r = count(tr->right);
		return l + r + 1;
	}
	void print_pre(const Node * tr, std::ofstream &file) const
	{
		try
		{
			if (!tr) throw 1;
		}
		catch (int)
		{
			return;
		}
		file << tr->value_ << "  ";
		if (tr->left)
			print_pre(tr->left, file);
		if (tr->right)
			print_pre(tr->right, file);
	}
	void Delete(Node **Tree, T &value)
	{
		Node *q;

		if (*Tree == nullptr) return;
		else
			if (value<(**Tree).value_) Delete(&((**Tree).left), value);
			else
				if (value>(**Tree).value_) Delete(&((**Tree).right), value);
				else {
					q = *Tree;
					if ((*q).right ==nullptr) { *Tree = (*q).left; delete q; }
					else
						if ((*q).left == nullptr) { *Tree = (*q).right; delete q; }
						else Delete_(&((*q).left), &q);
				}
	}
	void Delete_(Node **r, Node **q)
	{
		Node *s;

		if ((**r).right == nullptr)
		{
			(**q).value_ = (**r).value_; *q = *r;
			s = *r; *r = (**r).left; delete s;
		}
		else Delete_(&((**r).right), q);
	}

public:
	Tree()
	{
		root = nullptr;
	};
	~Tree()
	{
		null_tree(root);
	};
	Node* tree_one()
	{
		return root;
	};
	void file_tree(char* name);
	bool add(const T &value);
	bool find(const T &value);
	void print(ostream &out) const;
	int count_() const;
	bool del(T value)
	{
		try
		{
			if (find(value) == 0) throw 1;
		}
		catch (int)
		{
			return 0;
		}

		Delete(&root, value);
		return !find(value);
	}
	void pr(char* name) const;
};
template <class T>
void Tree<T>::pr(char* name) const
{
	ofstream file(name);
	if (file.is_open())
	{
		file << count_() << " ";
		print_pre(root, file);

		file.close();
	}
}
template <class T>
int Tree<T>::count_() const
{
	return count(root);
}
template <class T>
void  Tree<T>::print(ostream &out) const
{
	root->show(out, 0);
}
template <class T>
void Tree<T>::Node::show(ostream &out, int level) const
{
	const Node *tr = this;
	if (tr) tr->right->show(out, level + 1);
	for (int i = 0; i<level; i++)
		out << "   ";
	if (tr) out << tr->value_ << endl;
	else out << "End" << endl;
	if (tr) tr->left->show(out, level + 1);
}
template <class T>
bool Tree<T>::add(const T &value)
{
	Node *tr = add_(value);
	if (tr) return true;
	else    return false;
}
template <class T>
void Tree<T>::file_tree(char* name)
{
	ifstream file(name);
	try
	{
		if (file.is_open()==0) throw 1;
	}
	catch (int)
	{
		return 0;
	}

	if (file.is_open())
	{
		int i_max;
		file >> i_max;
		for (int i = 0; i < i_max; ++i)
		{
			T node;
			file >> node;
			add(node);
		}
		file.close();
	}
}
template <class T>
bool Tree<T>::find(const T &value)
{
	Node *tr = find_(value);
	if (tr) return true;
	else    return false;
}
<|endoftext|>


<commit_before>#include "Viewer.hpp"
#include "Physics/Env.hpp"
#include "Config.hpp"

#include <QApplication>

#include <NxPhysics.h>
#include <stdio.h>

using namespace std;

void usage(const char* prog)
{
	fprintf(stderr, "usage: %s -c <config file> [--ui] [--sv]\n", prog);
	fprintf(stderr, "\t--ui    Show GUI\n");
	fprintf(stderr, "\t--sv    Use shared vision multicast port\n");
}

int main(int argc, char* argv[])
{
	QApplication app(argc, argv);

	Env* env = new Env();

	char* configFile = 0;
	bool useGUI = false;
	bool sendShared = false;

	//loop arguments and look for config file
	for (int i=1 ; i<argc ; ++i)
	{
		if (strcmp(argv[i], "--ui") == 0)
		{
			useGUI = true;
		} else if (strcmp(argv[i], "--sv") == 0)
		{
			sendShared = true;
		} else if (strcmp(argv[i], "-c") == 0)
		{
			++i;
			if (i < argc)
			{
				configFile = argv[i];
			}
			else
			{
				printf ("Expected config file after -c parameter\n");
				return 0;
			}
		} else {
			printf("%s is not recognized as a valid flag\n", argv[i]);
			return 0;
		}
	}

	env->sendShared = sendShared;

	Config* config = 0;

	if (configFile)
	{
		config = new Config(configFile, env);
	}
	else
	{
		usage(argv[0]);
		exit(0);
	}

	Viewer *win = 0;
	if (useGUI)
	{
		win = new Viewer(env);
		win->setVisible(true);
	}
	int ret = app.exec();

	//cleanup
	delete win;
	delete env;

	delete config;

	return ret;
}
<commit_msg>Simulator has default configuration file<commit_after>#include "Viewer.hpp"
#include "Physics/Env.hpp"
#include "Config.hpp"

#include <QApplication>
#include <QFile>

#include <stdio.h>

using namespace std;

void usage(const char* prog)
{
	fprintf(stderr, "usage: %s [-c <config file>] [--ui] [--sv]\n", prog);
	fprintf(stderr, "\t--ui    Show GUI\n");
	fprintf(stderr, "\t--sv    Use shared vision multicast port\n");
}

int main(int argc, char* argv[])
{
	QApplication app(argc, argv);

	Env* env = new Env();

	QString configFile = "simulator.cfg";
	bool useGUI = false;
	bool sendShared = false;

	//loop arguments and look for config file
	for (int i=1 ; i<argc ; ++i)
	{
		if (strcmp(argv[i], "--ui") == 0)
		{
			useGUI = true;
		} else if (strcmp(argv[i], "--sv") == 0)
		{
			sendShared = true;
		} else if (strcmp(argv[i], "-c") == 0)
		{
			++i;
			if (i < argc)
			{
				configFile = argv[i];
			}
			else
			{
				printf ("Expected config file after -c parameter\n");
				return 0;
			}
		} else {
			printf("%s is not recognized as a valid flag\n", argv[i]);
			return 0;
		}
	}

	env->sendShared = sendShared;

	if (!QFile(configFile).exists())
	{
		fprintf(stderr, "Configuration file %s does not exist\n", (const char *)configFile.toAscii());
		return 1;
	}

	Config* config = 0;
	config = new Config(configFile, env);

	Viewer *win = 0;
	if (useGUI)
	{
		win = new Viewer(env);
		win->setVisible(true);
	}
	int ret = app.exec();

	//cleanup
	delete win;
	delete env;

	delete config;

	return ret;
}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"

#include "OgreMovableObject.h"
#include "OgreSceneNode.h"
#include "OgreTagPoint.h"
#include "OgreLight.h"
#include "OgreEntity.h"
#include "OgreRoot.h"
#include "OgreSceneManager.h"
#include "OgreCamera.h"
#include "OgreLodListener.h"

namespace Ogre {
	//-----------------------------------------------------------------------
	//-----------------------------------------------------------------------
	uint32 MovableObject::msDefaultQueryFlags = 0xFFFFFFFF;
	uint32 MovableObject::msDefaultVisibilityFlags = 0xFFFFFFFF;
    //-----------------------------------------------------------------------
    MovableObject::MovableObject()
        : mCreator(0)
        , mManager(0)
        , mParentNode(0)
        , mParentIsTagPoint(false)
        , mVisible(true)
		, mDebugDisplay(false)
        , mUpperDistance(0)
        , mSquaredUpperDistance(0)
        , mBeyondFarDistance(false)
        , mRenderQueueID(RENDER_QUEUE_MAIN)
        , mRenderQueueIDSet(false)
        , mQueryFlags(msDefaultQueryFlags)
        , mVisibilityFlags(msDefaultVisibilityFlags)
        , mCastShadows(true)
        , mRenderingDisabled(false)
        , mListener(0)
        , mLightListUpdated(0)
		, mLightMask(0xFFFFFFFF)
    {
    }
    //-----------------------------------------------------------------------
    MovableObject::MovableObject(const String& name)
        : mName(name)
        , mCreator(0)
        , mManager(0)
        , mParentNode(0)
        , mParentIsTagPoint(false)
        , mVisible(true)
		, mDebugDisplay(false)
        , mUpperDistance(0)
        , mSquaredUpperDistance(0)
        , mBeyondFarDistance(false)
        , mRenderQueueID(RENDER_QUEUE_MAIN)
        , mRenderQueueIDSet(false)
        , mQueryFlags(msDefaultQueryFlags)
        , mVisibilityFlags(msDefaultVisibilityFlags)
        , mCastShadows(true)
        , mRenderingDisabled(false)
        , mListener(0)
        , mLightListUpdated(0)
		, mLightMask(0xFFFFFFFF)
    {
    }
    //-----------------------------------------------------------------------
    MovableObject::~MovableObject()
    {
        // Call listener (note, only called if there's something to do)
        if (mListener)
        {
            mListener->objectDestroyed(this);
        }

        if (mParentNode)
        {
            // detach from parent
            if (mParentIsTagPoint)
            {
                // May be we are a lod entity which not in the parent entity child object list,
                // call this method could safely ignore this case.
                static_cast<TagPoint*>(mParentNode)->getParentEntity()->detachObjectFromBone(this);
            }
            else
            {
                // May be we are a lod entity which not in the parent node child object list,
                // call this method could safely ignore this case.
                static_cast<SceneNode*>(mParentNode)->detachObject(this);
            }
        }
    }
    //-----------------------------------------------------------------------
    void MovableObject::_notifyAttached(Node* parent, bool isTagPoint)
    {
        assert(!mParentNode || !parent);

        bool different = (parent != mParentNode);

        mParentNode = parent;
        mParentIsTagPoint = isTagPoint;

        // Mark light list being dirty, simply decrease
        // counter by one for minimise overhead
        --mLightListUpdated;

        // Call listener (note, only called if there's something to do)
        if (mListener && different)
        {
            if (mParentNode)
                mListener->objectAttached(this);
            else
                mListener->objectDetached(this);
        }
    }
    //-----------------------------------------------------------------------
    Node* MovableObject::getParentNode(void) const
    {
        return mParentNode;
    }
    //-----------------------------------------------------------------------
    SceneNode* MovableObject::getParentSceneNode(void) const
    {
        if (mParentIsTagPoint)
        {
            TagPoint* tp = static_cast<TagPoint*>(mParentNode);
            return tp->getParentEntity()->getParentSceneNode();
        }
        else
        {
            return static_cast<SceneNode*>(mParentNode);
        }
    }
    //-----------------------------------------------------------------------
    bool MovableObject::isAttached(void) const
    {
        return (mParentNode != 0);

    }
	//---------------------------------------------------------------------
	void MovableObject::detachFromParent(void)
	{
		if (isAttached())
		{
			if (mParentIsTagPoint)
			{
				TagPoint* tp = static_cast<TagPoint*>(mParentNode);
				tp->getParentEntity()->detachObjectFromBone(this);
			}
			else
			{
				SceneNode* sn = static_cast<SceneNode*>(mParentNode);
				sn->detachObject(this);
			}
		}
	}
    //-----------------------------------------------------------------------
	bool MovableObject::isInScene(void) const
	{
		if (mParentNode != 0)
		{
			if (mParentIsTagPoint)
			{
				TagPoint* tp = static_cast<TagPoint*>(mParentNode);
				return tp->getParentEntity()->isInScene();
			}
			else
			{
				SceneNode* sn = static_cast<SceneNode*>(mParentNode);
				return sn->isInSceneGraph();
			}
		}
		else
		{
			return false;
		}
	}
    //-----------------------------------------------------------------------
    void MovableObject::_notifyMoved(void)
    {
        // Mark light list being dirty, simply decrease
        // counter by one for minimise overhead
        --mLightListUpdated;

        // Notify listener if exists
        if (mListener)
        {
            mListener->objectMoved(this);
        }
    }
    //-----------------------------------------------------------------------
    void MovableObject::setVisible(bool visible)
    {
        mVisible = visible;
    }
    //-----------------------------------------------------------------------
    bool MovableObject::getVisible(void) const
    {
        return mVisible;
    }
    //-----------------------------------------------------------------------
    bool MovableObject::isVisible(void) const
    {
        if (!mVisible || mBeyondFarDistance || mRenderingDisabled)
            return false;

        SceneManager* sm = Root::getSingleton()._getCurrentSceneManager();
        if (sm && !(getVisibilityFlags() & sm->_getCombinedVisibilityMask()))
            return false;

        return true;
    }
	//-----------------------------------------------------------------------
	void MovableObject::_notifyCurrentCamera(Camera* cam)
	{
		if (mParentNode)
		{
			if (cam->getUseRenderingDistance() && mUpperDistance > 0)
			{
				Real rad = getBoundingRadius();
				Real squaredDepth = mParentNode->getSquaredViewDepth(cam->getLodCamera());
				// Max distance to still render
				Real maxDist = mUpperDistance + rad;
				if (squaredDepth > Math::Sqr(maxDist))
				{
					mBeyondFarDistance = true;
				}
				else
				{
					mBeyondFarDistance = false;
				}
			}
			else
			{
				mBeyondFarDistance = false;
			}

            // Construct event object
            MovableObjectLodChangedEvent evt;
            evt.movableObject = this;
            evt.camera = cam;

            // Notify lod event listeners
            cam->getSceneManager()->_notifyMovableObjectLodChanged(evt);

		}

        mRenderingDisabled = mListener && !mListener->objectRendering(this, cam);
	}
    //-----------------------------------------------------------------------
    void MovableObject::setRenderQueueGroup(uint8 queueID)
    {
		assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!");
        mRenderQueueID = queueID;
        mRenderQueueIDSet = true;
    }
    //-----------------------------------------------------------------------
    uint8 MovableObject::getRenderQueueGroup(void) const
    {
        return mRenderQueueID;
    }
    //-----------------------------------------------------------------------
	const Matrix4& MovableObject::_getParentNodeFullTransform(void) const
	{

		if(mParentNode)
		{
			// object attached to a sceneNode
			return mParentNode->_getFullTransform();
		}
        // fallback
        return Matrix4::IDENTITY;
	}
    //-----------------------------------------------------------------------
    const AxisAlignedBox& MovableObject::getWorldBoundingBox(bool derive) const
    {
        if (derive)
        {
            mWorldAABB = this->getBoundingBox();
            mWorldAABB.transformAffine(_getParentNodeFullTransform());
        }

        return mWorldAABB;

    }
    //-----------------------------------------------------------------------
	const Sphere& MovableObject::getWorldBoundingSphere(bool derive) const
	{
		if (derive)
		{
			mWorldBoundingSphere.setRadius(getBoundingRadius());
			mWorldBoundingSphere.setCenter(mParentNode->_getDerivedPosition());
		}
		return mWorldBoundingSphere;
	}
    //-----------------------------------------------------------------------
    const LightList& MovableObject::queryLights(void) const
    {
        // Try listener first
        if (mListener)
        {
            const LightList* lightList =
                mListener->objectQueryLights(this);
            if (lightList)
            {
                return *lightList;
            }
        }

        // Query from parent entity if exists
        if (mParentIsTagPoint)
        {
            TagPoint* tp = static_cast<TagPoint*>(mParentNode);
            return tp->getParentEntity()->queryLights();
        }

        if (mParentNode)
        {
            SceneNode* sn = static_cast<SceneNode*>(mParentNode);

            // Make sure we only update this only if need.
            ulong frame = sn->getCreator()->_getLightsDirtyCounter();
            if (mLightListUpdated != frame)
            {
                mLightListUpdated = frame;

                sn->findLights(mLightList, this->getBoundingRadius(), this->getLightMask());
            }
        }
        else
        {
            mLightList.clear();
        }

        return mLightList;
    }
    //-----------------------------------------------------------------------
    ShadowCaster::ShadowRenderableListIterator MovableObject::getShadowVolumeRenderableIterator(
        ShadowTechnique shadowTechnique, const Light* light,
        HardwareIndexBufferSharedPtr* indexBuffer,
        bool extrudeVertices, Real extrusionDist, unsigned long flags )
    {
        static ShadowRenderableList dummyList;
        return ShadowRenderableListIterator(dummyList.begin(), dummyList.end());
    }
    //-----------------------------------------------------------------------
    const AxisAlignedBox& MovableObject::getLightCapBounds(void) const
    {
        // Same as original bounds
        return getWorldBoundingBox();
    }
    //-----------------------------------------------------------------------
    const AxisAlignedBox& MovableObject::getDarkCapBounds(const Light& light, Real extrusionDist) const
    {
        // Extrude own light cap bounds
        mWorldDarkCapBounds = getLightCapBounds();
        this->extrudeBounds(mWorldDarkCapBounds, light.getAs4DVector(),
            extrusionDist);
        return mWorldDarkCapBounds;

    }
    //-----------------------------------------------------------------------
    Real MovableObject::getPointExtrusionDistance(const Light* l) const
    {
        if (mParentNode)
        {
            return getExtrusionDistance(mParentNode->_getDerivedPosition(), l);
        }
        else
        {
            return 0;
        }
    }
	//-----------------------------------------------------------------------
	uint32 MovableObject::getTypeFlags(void) const
	{
		if (mCreator)
		{
			return mCreator->getTypeFlags();
		}
		else
		{
			return 0xFFFFFFFF;
		}
	}
	//---------------------------------------------------------------------
	void MovableObject::setLightMask(uint32 lightMask)
	{
		this->mLightMask = lightMask;
		//make sure to request a new light list from the scene manager if mask changed
		mLightListUpdated = 0;
	}
	//---------------------------------------------------------------------
	class MORecvShadVisitor : public Renderable::Visitor
	{
	public:
		bool anyReceiveShadows;
		MORecvShadVisitor() : anyReceiveShadows(false)
		{

		}
		void visit(Renderable* rend, ushort lodIndex, bool isDebug,
			Any* pAny = 0)
		{
			Technique* tech = rend->getTechnique();
			bool techReceivesShadows = tech && tech->getParent()->getReceiveShadows();
			anyReceiveShadows = anyReceiveShadows ||
				techReceivesShadows || !tech;
		}
	};
	//---------------------------------------------------------------------
	bool MovableObject::getReceivesShadows()
	{
		MORecvShadVisitor visitor;
		visitRenderables(&visitor);
		return visitor.anyReceiveShadows;

	}
	//-----------------------------------------------------------------------
	//-----------------------------------------------------------------------
	MovableObject* MovableObjectFactory::createInstance(
		const String& name, SceneManager* manager,
		const NameValuePairList* params)
	{
		MovableObject* m = createInstanceImpl(name, params);
		m->_notifyCreator(this);
		m->_notifyManager(manager);
		return m;
	}

}

<commit_msg>Patch 2901062: If you use 2 or more scenemanager and call isVisible() outside of _findVisibleObjects(), current scene manager might be dangling pointer. This change is ok in the current context because a MovableObject is always permanently linked to its parent SceneManager. This may change in future.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"

#include "OgreMovableObject.h"
#include "OgreSceneNode.h"
#include "OgreTagPoint.h"
#include "OgreLight.h"
#include "OgreEntity.h"
#include "OgreRoot.h"
#include "OgreSceneManager.h"
#include "OgreCamera.h"
#include "OgreLodListener.h"

namespace Ogre {
	//-----------------------------------------------------------------------
	//-----------------------------------------------------------------------
	uint32 MovableObject::msDefaultQueryFlags = 0xFFFFFFFF;
	uint32 MovableObject::msDefaultVisibilityFlags = 0xFFFFFFFF;
    //-----------------------------------------------------------------------
    MovableObject::MovableObject()
        : mCreator(0)
        , mManager(0)
        , mParentNode(0)
        , mParentIsTagPoint(false)
        , mVisible(true)
		, mDebugDisplay(false)
        , mUpperDistance(0)
        , mSquaredUpperDistance(0)
        , mBeyondFarDistance(false)
        , mRenderQueueID(RENDER_QUEUE_MAIN)
        , mRenderQueueIDSet(false)
        , mQueryFlags(msDefaultQueryFlags)
        , mVisibilityFlags(msDefaultVisibilityFlags)
        , mCastShadows(true)
        , mRenderingDisabled(false)
        , mListener(0)
        , mLightListUpdated(0)
		, mLightMask(0xFFFFFFFF)
    {
    }
    //-----------------------------------------------------------------------
    MovableObject::MovableObject(const String& name)
        : mName(name)
        , mCreator(0)
        , mManager(0)
        , mParentNode(0)
        , mParentIsTagPoint(false)
        , mVisible(true)
		, mDebugDisplay(false)
        , mUpperDistance(0)
        , mSquaredUpperDistance(0)
        , mBeyondFarDistance(false)
        , mRenderQueueID(RENDER_QUEUE_MAIN)
        , mRenderQueueIDSet(false)
        , mQueryFlags(msDefaultQueryFlags)
        , mVisibilityFlags(msDefaultVisibilityFlags)
        , mCastShadows(true)
        , mRenderingDisabled(false)
        , mListener(0)
        , mLightListUpdated(0)
		, mLightMask(0xFFFFFFFF)
    {
    }
    //-----------------------------------------------------------------------
    MovableObject::~MovableObject()
    {
        // Call listener (note, only called if there's something to do)
        if (mListener)
        {
            mListener->objectDestroyed(this);
        }

        if (mParentNode)
        {
            // detach from parent
            if (mParentIsTagPoint)
            {
                // May be we are a lod entity which not in the parent entity child object list,
                // call this method could safely ignore this case.
                static_cast<TagPoint*>(mParentNode)->getParentEntity()->detachObjectFromBone(this);
            }
            else
            {
                // May be we are a lod entity which not in the parent node child object list,
                // call this method could safely ignore this case.
                static_cast<SceneNode*>(mParentNode)->detachObject(this);
            }
        }
    }
    //-----------------------------------------------------------------------
    void MovableObject::_notifyAttached(Node* parent, bool isTagPoint)
    {
        assert(!mParentNode || !parent);

        bool different = (parent != mParentNode);

        mParentNode = parent;
        mParentIsTagPoint = isTagPoint;

        // Mark light list being dirty, simply decrease
        // counter by one for minimise overhead
        --mLightListUpdated;

        // Call listener (note, only called if there's something to do)
        if (mListener && different)
        {
            if (mParentNode)
                mListener->objectAttached(this);
            else
                mListener->objectDetached(this);
        }
    }
    //-----------------------------------------------------------------------
    Node* MovableObject::getParentNode(void) const
    {
        return mParentNode;
    }
    //-----------------------------------------------------------------------
    SceneNode* MovableObject::getParentSceneNode(void) const
    {
        if (mParentIsTagPoint)
        {
            TagPoint* tp = static_cast<TagPoint*>(mParentNode);
            return tp->getParentEntity()->getParentSceneNode();
        }
        else
        {
            return static_cast<SceneNode*>(mParentNode);
        }
    }
    //-----------------------------------------------------------------------
    bool MovableObject::isAttached(void) const
    {
        return (mParentNode != 0);

    }
	//---------------------------------------------------------------------
	void MovableObject::detachFromParent(void)
	{
		if (isAttached())
		{
			if (mParentIsTagPoint)
			{
				TagPoint* tp = static_cast<TagPoint*>(mParentNode);
				tp->getParentEntity()->detachObjectFromBone(this);
			}
			else
			{
				SceneNode* sn = static_cast<SceneNode*>(mParentNode);
				sn->detachObject(this);
			}
		}
	}
    //-----------------------------------------------------------------------
	bool MovableObject::isInScene(void) const
	{
		if (mParentNode != 0)
		{
			if (mParentIsTagPoint)
			{
				TagPoint* tp = static_cast<TagPoint*>(mParentNode);
				return tp->getParentEntity()->isInScene();
			}
			else
			{
				SceneNode* sn = static_cast<SceneNode*>(mParentNode);
				return sn->isInSceneGraph();
			}
		}
		else
		{
			return false;
		}
	}
    //-----------------------------------------------------------------------
    void MovableObject::_notifyMoved(void)
    {
        // Mark light list being dirty, simply decrease
        // counter by one for minimise overhead
        --mLightListUpdated;

        // Notify listener if exists
        if (mListener)
        {
            mListener->objectMoved(this);
        }
    }
    //-----------------------------------------------------------------------
    void MovableObject::setVisible(bool visible)
    {
        mVisible = visible;
    }
    //-----------------------------------------------------------------------
    bool MovableObject::getVisible(void) const
    {
        return mVisible;
    }
    //-----------------------------------------------------------------------
    bool MovableObject::isVisible(void) const
    {
        if (!mVisible || mBeyondFarDistance || mRenderingDisabled)
            return false;

        if (mManager && !(getVisibilityFlags() & mManager->_getCombinedVisibilityMask()))
            return false;

        return true;
    }
	//-----------------------------------------------------------------------
	void MovableObject::_notifyCurrentCamera(Camera* cam)
	{
		if (mParentNode)
		{
			if (cam->getUseRenderingDistance() && mUpperDistance > 0)
			{
				Real rad = getBoundingRadius();
				Real squaredDepth = mParentNode->getSquaredViewDepth(cam->getLodCamera());
				// Max distance to still render
				Real maxDist = mUpperDistance + rad;
				if (squaredDepth > Math::Sqr(maxDist))
				{
					mBeyondFarDistance = true;
				}
				else
				{
					mBeyondFarDistance = false;
				}
			}
			else
			{
				mBeyondFarDistance = false;
			}

            // Construct event object
            MovableObjectLodChangedEvent evt;
            evt.movableObject = this;
            evt.camera = cam;

            // Notify lod event listeners
            cam->getSceneManager()->_notifyMovableObjectLodChanged(evt);

		}

        mRenderingDisabled = mListener && !mListener->objectRendering(this, cam);
	}
    //-----------------------------------------------------------------------
    void MovableObject::setRenderQueueGroup(uint8 queueID)
    {
		assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!");
        mRenderQueueID = queueID;
        mRenderQueueIDSet = true;
    }
    //-----------------------------------------------------------------------
    uint8 MovableObject::getRenderQueueGroup(void) const
    {
        return mRenderQueueID;
    }
    //-----------------------------------------------------------------------
	const Matrix4& MovableObject::_getParentNodeFullTransform(void) const
	{

		if(mParentNode)
		{
			// object attached to a sceneNode
			return mParentNode->_getFullTransform();
		}
        // fallback
        return Matrix4::IDENTITY;
	}
    //-----------------------------------------------------------------------
    const AxisAlignedBox& MovableObject::getWorldBoundingBox(bool derive) const
    {
        if (derive)
        {
            mWorldAABB = this->getBoundingBox();
            mWorldAABB.transformAffine(_getParentNodeFullTransform());
        }

        return mWorldAABB;

    }
    //-----------------------------------------------------------------------
	const Sphere& MovableObject::getWorldBoundingSphere(bool derive) const
	{
		if (derive)
		{
			mWorldBoundingSphere.setRadius(getBoundingRadius());
			mWorldBoundingSphere.setCenter(mParentNode->_getDerivedPosition());
		}
		return mWorldBoundingSphere;
	}
    //-----------------------------------------------------------------------
    const LightList& MovableObject::queryLights(void) const
    {
        // Try listener first
        if (mListener)
        {
            const LightList* lightList =
                mListener->objectQueryLights(this);
            if (lightList)
            {
                return *lightList;
            }
        }

        // Query from parent entity if exists
        if (mParentIsTagPoint)
        {
            TagPoint* tp = static_cast<TagPoint*>(mParentNode);
            return tp->getParentEntity()->queryLights();
        }

        if (mParentNode)
        {
            SceneNode* sn = static_cast<SceneNode*>(mParentNode);

            // Make sure we only update this only if need.
            ulong frame = sn->getCreator()->_getLightsDirtyCounter();
            if (mLightListUpdated != frame)
            {
                mLightListUpdated = frame;

                sn->findLights(mLightList, this->getBoundingRadius(), this->getLightMask());
            }
        }
        else
        {
            mLightList.clear();
        }

        return mLightList;
    }
    //-----------------------------------------------------------------------
    ShadowCaster::ShadowRenderableListIterator MovableObject::getShadowVolumeRenderableIterator(
        ShadowTechnique shadowTechnique, const Light* light,
        HardwareIndexBufferSharedPtr* indexBuffer,
        bool extrudeVertices, Real extrusionDist, unsigned long flags )
    {
        static ShadowRenderableList dummyList;
        return ShadowRenderableListIterator(dummyList.begin(), dummyList.end());
    }
    //-----------------------------------------------------------------------
    const AxisAlignedBox& MovableObject::getLightCapBounds(void) const
    {
        // Same as original bounds
        return getWorldBoundingBox();
    }
    //-----------------------------------------------------------------------
    const AxisAlignedBox& MovableObject::getDarkCapBounds(const Light& light, Real extrusionDist) const
    {
        // Extrude own light cap bounds
        mWorldDarkCapBounds = getLightCapBounds();
        this->extrudeBounds(mWorldDarkCapBounds, light.getAs4DVector(),
            extrusionDist);
        return mWorldDarkCapBounds;

    }
    //-----------------------------------------------------------------------
    Real MovableObject::getPointExtrusionDistance(const Light* l) const
    {
        if (mParentNode)
        {
            return getExtrusionDistance(mParentNode->_getDerivedPosition(), l);
        }
        else
        {
            return 0;
        }
    }
	//-----------------------------------------------------------------------
	uint32 MovableObject::getTypeFlags(void) const
	{
		if (mCreator)
		{
			return mCreator->getTypeFlags();
		}
		else
		{
			return 0xFFFFFFFF;
		}
	}
	//---------------------------------------------------------------------
	void MovableObject::setLightMask(uint32 lightMask)
	{
		this->mLightMask = lightMask;
		//make sure to request a new light list from the scene manager if mask changed
		mLightListUpdated = 0;
	}
	//---------------------------------------------------------------------
	class MORecvShadVisitor : public Renderable::Visitor
	{
	public:
		bool anyReceiveShadows;
		MORecvShadVisitor() : anyReceiveShadows(false)
		{

		}
		void visit(Renderable* rend, ushort lodIndex, bool isDebug,
			Any* pAny = 0)
		{
			Technique* tech = rend->getTechnique();
			bool techReceivesShadows = tech && tech->getParent()->getReceiveShadows();
			anyReceiveShadows = anyReceiveShadows ||
				techReceivesShadows || !tech;
		}
	};
	//---------------------------------------------------------------------
	bool MovableObject::getReceivesShadows()
	{
		MORecvShadVisitor visitor;
		visitRenderables(&visitor);
		return visitor.anyReceiveShadows;

	}
	//-----------------------------------------------------------------------
	//-----------------------------------------------------------------------
	MovableObject* MovableObjectFactory::createInstance(
		const String& name, SceneManager* manager,
		const NameValuePairList* params)
	{
		MovableObject* m = createInstanceImpl(name, params);
		m->_notifyCreator(this);
		m->_notifyManager(manager);
		return m;
	}

}

<|endoftext|>


<commit_before>#ifndef STACK_HPP
#define STACK_HPP

#include <iostream>

template <class T>
class Stack {
public:
	Stack ( ) : capacity (13), size (0), stack ( stack = new T*[capacity]) { }

	Stack (int c) : capacity (c), size (0), stack (nullptr) {
		if (c < 0) { capacity = 0; }
		stack = new T*[capacity];
	}

	Stack (const Stack& rhs) : capacity (rhs.capacity), stack (nullptr) {
		stack = new T*[capacity];
		for (size = 0; size < rhs.size; ++size) {
			stack[size] = new T (*rhs.stack[size]);
		}
	}

	~Stack ( ) {
		for (int i = 0; i < size; ++i) {
			delete stack[i];
		}
		delete[] stack;
	}

	int getSize ( ) const {
		return size;
	}

	int getTotalCapacity ( ) const {
		return capacity;
	}

	bool isEmpty ( ) const {
		return size == 0;
	}

	bool isFull ( ) const {
		return size == capacity;
	}

	T* peek ( ) const {
		return stack[size - 1];
	}

	T* pop ( ) {
		if (! isEmpty ( )) {
			return stack[--size];
		}
		return nullptr;
	}

	void push (T* c) {
		if(!isFull()) {
			stack[size++] = c;
		}
	}

	Stack& operator=(const Stack& rhs) {
		if (this != &rhs) {
			for (int i = 0; i < size; ++i) {
				delete stack[i];
			}
			delete[] stack;

			capacity = rhs.capacity;
			stack = new T*[capacity];
			for (size = 0; size < rhs.size; ++size) {
				stack[size] = new T (*rhs.stack[size]);
			}
		}
		return *this;
	}

	friend std::ostream& operator<<(std::ostream& output, const Stack& currentStack) {
		for (int i = currentStack.size - 1; i >= 0; --i) {
			output << *currentStack.stack[i] << "\n";
		}
		return output;
	}

private:
	int capacity;
	int size;
	T** stack;
};

#endif
<commit_msg>Moves Stack implementation to outside of the class<commit_after>#ifndef STACK_HPP
#define STACK_HPP

#include <iostream>

template <class T>
class Stack {
public:
	Stack ( );

	Stack(int c);

	Stack(const Stack& rhs);

	Stack& operator=(const Stack& rhs);

	~Stack( );

	int getSize( ) const;

	int getTotalCapacity( ) const;

	bool isEmpty( ) const;

	bool isFull( ) const;

	T* peek( ) const;

	T* pop( );

	void push(T* c);

	friend std::ostream& operator<<(std::ostream& output, const Stack& currentStack) {
		for (int i = currentStack.size - 1; i >= 0; --i) {
			output << *currentStack.stack[i] << "\n";
		}
		return output;
	}

private:
	int capacity;
	int size;
	T** stack;
};

template <class T>
Stack<T>::Stack ( ) : capacity (13), size (0), stack (stack = new T*[capacity]) { }

template <class T>
Stack<T>::Stack(int c): capacity (c), size (0), stack (nullptr) {
	if (c < 0) { capacity = 0; }
	stack = new T*[capacity];
}

template <class T>
Stack<T>::Stack(const Stack& rhs): capacity (rhs.capacity), stack (nullptr) {
	stack = new T*[capacity];
	for (size = 0; size < rhs.size; ++size) {
		stack[size] = new T (*rhs.stack[size]);
	}
}

template <class T>
Stack<T>::~Stack( ) {
	for (int i = 0; i < size; ++i) {
		delete stack[i];
	}
	delete[] stack;
}

template <class T>
int Stack<T>::getSize( ) const {
	return size;
}

template <class T>
int Stack<T>::getTotalCapacity( ) const {
	return capacity;
}

template <class T>
bool Stack<T>::isEmpty( ) const {
	return size == 0;
}

template <class T>
bool Stack<T>::isFull( ) const {
	return size == capacity;
}

template <class T>
T* Stack<T>::peek( ) const {
	return stack[size - 1];
}

template <class T>
T* Stack<T>::pop( ) {
	if (! isEmpty ( )) {
		return stack[--size];
	}
	return nullptr;
}

template <class T>
void Stack<T>::push(T* c) {
	if(!isFull()) {
		stack[size++] = c;
	}
}

template <class T>
Stack<T>& Stack<T>::operator=(const Stack& rhs) {
	if (this != &rhs) {
		for (int i = 0; i < size; ++i) {
			delete stack[i];
		}
		delete[] stack;

		capacity = rhs.capacity;
		stack = new T*[capacity];
		for (size = 0; size < rhs.size; ++size) {
			stack[size] = new T (*rhs.stack[size]);
		}
	}
	return *this;
}
#endif
<|endoftext|>


<commit_before>#ifndef AUTOCHECK_GENERATOR_HPP
#define AUTOCHECK_GENERATOR_HPP

#include <random>
#include <vector>
#include <iterator>
#include <limits>
#include <algorithm>

#include "is_one_of.hpp"
#include "function.hpp"
#include "generator_combinators.hpp"
#include "apply.hpp"

namespace autocheck {

  /* Reusable static standard random number generator. */
  inline std::mt19937& rng() {
    static std::random_device rd;
    static std::mt19937 rng(rd());
    return rng;
  }

  template <typename T, typename... Gens, int... Is>
  T generate(std::tuple<Gens...>& gens, size_t size,
      const range<0, Is...>&)
  {
    return T(std::get<Is>(gens)(size)...);
  }

  template <typename T, typename... Gens>
  T generate(std::tuple<Gens...>& gens, size_t size) {
    return generate<T>(gens, size, range<sizeof...(Gens)>());
  }

  /* Generators produce an infinite sequence. */

  template <typename T, typename Enable = void>
  class generator;

  template <>
  class generator<bool> {
    public:
      typedef bool result_type;

      result_type operator() (size_t = 0) {
        static std::bernoulli_distribution dist(0.5);
        return dist(rng());
      }
  };

  namespace detail {

    static const char alnums[]  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      "abcdefghijklmnopqrstuvwxyz"
      "0123456789";
    /* Subtract 1 for NUL terminator. */
    static const size_t nalnums = sizeof(alnums) - 1;
    static const size_t nprint  = '~' - ' ' + 1;

  }

  enum CharCategory {
    ccAlphaNumeric,
    ccPrintable,
    ccAny
  };

  template <typename CharType, CharCategory Category = ccPrintable>
  class char_generator {
    public:
      typedef CharType result_type;

      result_type operator() (size_t size = 0) {
        if (Category == ccAlphaNumeric || size < detail::nalnums) {
          size = detail::nalnums - 1;
        } else if (Category == ccPrintable || size < detail::nprint) {
          size = detail::nprint - 1;
        } else {
          size = std::numeric_limits<CharType>::max();
        }
        /* Distribution is non-static. */
        std::uniform_int_distribution<int> dist(0, size);
        auto i = dist(rng());
        auto rv =
          (size < detail::nalnums) ? detail::alnums[i] :
          ((size < detail::nprint) ? ' ' + i :
           i);
        return rv;
      }
  };

  /* WARNING: wchar_t, char16_t, char32_t, and family are typedefs. They
   * cannot be distinguished from regular (un)signed integrals, meaning we
   * cannot provide a general `generator` for them with the special char
   * consideration of size. If you want that consideration, use
   * char_generator specifically. */

  template <typename CharType>
  class generator<
    CharType,
    typename std::enable_if<
      is_one_of<CharType, unsigned char, char, signed char>::value
    >::type
  > : public char_generator<CharType> {};

  template <typename UnsignedIntegral>
  class generator<
    UnsignedIntegral,
    typename std::enable_if<
      is_one_of<UnsignedIntegral, unsigned short, unsigned int,
        unsigned long, unsigned long long>::value
    >::type
  >
  {
    public:
      typedef UnsignedIntegral result_type;

      result_type operator() (size_t size = 0) {
        /* Distribution is non-static. */
        std::uniform_int_distribution<UnsignedIntegral> dist(0, size);
        auto rv = dist(rng());
        return rv;
      }
  };

  template <typename SignedIntegral>
  class generator<
    SignedIntegral,
    typename std::enable_if<
      is_one_of<SignedIntegral, short, int, long, long long>::value
    >::type
  >
  {
    public:
      typedef SignedIntegral result_type;

      result_type operator() (size_t size = 0) {
        /* Distribution is non-static. */
        std::uniform_int_distribution<SignedIntegral> dist(-size, size);
        auto rv = dist(rng());
        return rv;
      }
  };

  template <typename Floating>
  class generator<
    Floating,
    typename std::enable_if<
      is_one_of<Floating, float, double>::value
    >::type
  >
  {
    public:
      typedef Floating result_type;

      result_type operator() (size_t size = 0) {
        /* Distribution is non-static. */
        std::uniform_real_distribution<Floating> dist(-size, size);
        auto rv = dist(rng());
        return rv;
      }
  };

  template <typename CharGen = generator<char>>
  class string_generator {
    private:
      CharGen chargen;

    public:
      string_generator(const CharGen& chargen = CharGen()) :
        chargen(chargen) {}

      typedef std::basic_string<typename CharGen::result_type> result_type;

      result_type operator() (size_t size = 0) {
        result_type rv;
        rv.reserve(size);
        std::generate_n(std::back_insert_iterator<result_type>(rv), size,
            /* Scale characters faster than string size. */
            fix(size << 2, chargen));
        return rv;
      }
  };

  template <
    CharCategory Category = ccPrintable,
    typename CharType     = char
  >
  string_generator<char_generator<CharType, Category>> string() {
    return string_generator<char_generator<CharType, Category>>();
  }

  template <typename CharGen>
  string_generator<CharGen> string(const CharGen& chargen) {
    return string_generator<CharGen>();
  }

  template <typename CharType>
  class generator<std::basic_string<CharType>> :
    public string_generator<generator<CharType>> {};

  /* TODO: Generic sequence generator. */

  template <typename Gen>
  class list_generator {
    private:
      Gen eltgen;

    public:
      list_generator(const Gen& eltgen = Gen()) :
        eltgen(eltgen) {}

      typedef std::vector<typename Gen::result_type> result_type;

      result_type operator() (size_t size = 0) {
        result_type rv;
        rv.reserve(size);
        std::generate_n(std::back_insert_iterator<result_type>(rv), size,
            fix(size, eltgen));
        return rv;
      }
  };

  template <typename Gen>
  list_generator<Gen> list_of(const Gen& gen) {
    return list_generator<Gen>(gen);
  }

  template <typename T, typename Gen = generator<T>>
  list_generator<Gen> list_of() {
    return list_of(Gen());
  }

  template <typename T>
  class generator<std::vector<T>> : public list_generator<generator<T>> {};

  /* Ordered list combinator. */

  namespace detail {

    struct sorter {
      template <typename T>
      std::vector<T> operator() (std::vector<T>&& a, size_t) {
        std::sort(a.begin(), a.end());
        return a;
      }
    };

  }

  template <typename Gen>
  detail::mapped_generator<detail::sorter, list_generator<Gen>>
  ordered_list(const Gen& gen) {
    return map(detail::sorter(), list_of(gen));
  }

  template <typename T, typename Gen = generator<T>>
  detail::mapped_generator<detail::sorter, list_generator<Gen>>
  ordered_list() {
    return ordered_list(Gen());
  }

  /* Generic type generator (by construction). */

  template <typename T, typename... Gens>
  class cons_generator {
    private:
      std::tuple<Gens...> gens;

    public:
      cons_generator() :
        gens(Gens()...) {}

      cons_generator(const Gens&... gens) :
        gens(gens...) {}

      typedef T result_type;

      result_type operator() (size_t size = 0) {
        return generate<result_type>(gens, (size > 0) ? (size - 1) : size);
      }
  };

  template <typename T, typename... Gens>
  cons_generator<T, Gens...> cons(const Gens&... gens) {
    return cons_generator<T, Gens...>(gens...);
  }

  template <typename T, typename... Args>
  cons_generator<T, generator<Args>...> cons() {
    return cons_generator<T, generator<Args>...>();
  }

}

#endif

<commit_msg>fix ambiguity warnings for autocheck::generate<commit_after>#ifndef AUTOCHECK_GENERATOR_HPP
#define AUTOCHECK_GENERATOR_HPP

#include <random>
#include <vector>
#include <iterator>
#include <limits>
#include <algorithm>

#include "is_one_of.hpp"
#include "function.hpp"
#include "generator_combinators.hpp"
#include "apply.hpp"

namespace autocheck {

  /* Reusable static standard random number generator. */
  inline std::mt19937& rng() {
    static std::random_device rd;
    static std::mt19937 rng(rd());
    return rng;
  }

  template <typename T, typename... Gens, int... Is>
  T generate(std::tuple<Gens...>& gens, size_t size,
      const range<0, Is...>&)
  {
    return T(std::get<Is>(gens)(size)...);
  }

  template <typename T, typename... Gens>
  T generate(std::tuple<Gens...>& gens, size_t size) {
    return autocheck::generate<T>(gens, size, range<sizeof...(Gens)>());
  }

  /* Generators produce an infinite sequence. */

  template <typename T, typename Enable = void>
  class generator;

  template <>
  class generator<bool> {
    public:
      typedef bool result_type;

      result_type operator() (size_t = 0) {
        static std::bernoulli_distribution dist(0.5);
        return dist(rng());
      }
  };

  namespace detail {

    static const char alnums[]  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      "abcdefghijklmnopqrstuvwxyz"
      "0123456789";
    /* Subtract 1 for NUL terminator. */
    static const size_t nalnums = sizeof(alnums) - 1;
    static const size_t nprint  = '~' - ' ' + 1;

  }

  enum CharCategory {
    ccAlphaNumeric,
    ccPrintable,
    ccAny
  };

  template <typename CharType, CharCategory Category = ccPrintable>
  class char_generator {
    public:
      typedef CharType result_type;

      result_type operator() (size_t size = 0) {
        if (Category == ccAlphaNumeric || size < detail::nalnums) {
          size = detail::nalnums - 1;
        } else if (Category == ccPrintable || size < detail::nprint) {
          size = detail::nprint - 1;
        } else {
          size = std::numeric_limits<CharType>::max();
        }
        /* Distribution is non-static. */
        std::uniform_int_distribution<int> dist(0, size);
        auto i = dist(rng());
        auto rv =
          (size < detail::nalnums) ? detail::alnums[i] :
          ((size < detail::nprint) ? ' ' + i :
           i);
        return rv;
      }
  };

  /* WARNING: wchar_t, char16_t, char32_t, and family are typedefs. They
   * cannot be distinguished from regular (un)signed integrals, meaning we
   * cannot provide a general `generator` for them with the special char
   * consideration of size. If you want that consideration, use
   * char_generator specifically. */

  template <typename CharType>
  class generator<
    CharType,
    typename std::enable_if<
      is_one_of<CharType, unsigned char, char, signed char>::value
    >::type
  > : public char_generator<CharType> {};

  template <typename UnsignedIntegral>
  class generator<
    UnsignedIntegral,
    typename std::enable_if<
      is_one_of<UnsignedIntegral, unsigned short, unsigned int,
        unsigned long, unsigned long long>::value
    >::type
  >
  {
    public:
      typedef UnsignedIntegral result_type;

      result_type operator() (size_t size = 0) {
        /* Distribution is non-static. */
        std::uniform_int_distribution<UnsignedIntegral> dist(0, size);
        auto rv = dist(rng());
        return rv;
      }
  };

  template <typename SignedIntegral>
  class generator<
    SignedIntegral,
    typename std::enable_if<
      is_one_of<SignedIntegral, short, int, long, long long>::value
    >::type
  >
  {
    public:
      typedef SignedIntegral result_type;

      result_type operator() (size_t size = 0) {
        /* Distribution is non-static. */
        std::uniform_int_distribution<SignedIntegral> dist(-size, size);
        auto rv = dist(rng());
        return rv;
      }
  };

  template <typename Floating>
  class generator<
    Floating,
    typename std::enable_if<
      is_one_of<Floating, float, double>::value
    >::type
  >
  {
    public:
      typedef Floating result_type;

      result_type operator() (size_t size = 0) {
        /* Distribution is non-static. */
        std::uniform_real_distribution<Floating> dist(-size, size);
        auto rv = dist(rng());
        return rv;
      }
  };

  template <typename CharGen = generator<char>>
  class string_generator {
    private:
      CharGen chargen;

    public:
      string_generator(const CharGen& chargen = CharGen()) :
        chargen(chargen) {}

      typedef std::basic_string<typename CharGen::result_type> result_type;

      result_type operator() (size_t size = 0) {
        result_type rv;
        rv.reserve(size);
        std::generate_n(std::back_insert_iterator<result_type>(rv), size,
            /* Scale characters faster than string size. */
            fix(size << 2, chargen));
        return rv;
      }
  };

  template <
    CharCategory Category = ccPrintable,
    typename CharType     = char
  >
  string_generator<char_generator<CharType, Category>> string() {
    return string_generator<char_generator<CharType, Category>>();
  }

  template <typename CharGen>
  string_generator<CharGen> string(const CharGen& chargen) {
    return string_generator<CharGen>();
  }

  template <typename CharType>
  class generator<std::basic_string<CharType>> :
    public string_generator<generator<CharType>> {};

  /* TODO: Generic sequence generator. */

  template <typename Gen>
  class list_generator {
    private:
      Gen eltgen;

    public:
      list_generator(const Gen& eltgen = Gen()) :
        eltgen(eltgen) {}

      typedef std::vector<typename Gen::result_type> result_type;

      result_type operator() (size_t size = 0) {
        result_type rv;
        rv.reserve(size);
        std::generate_n(std::back_insert_iterator<result_type>(rv), size,
            fix(size, eltgen));
        return rv;
      }
  };

  template <typename Gen>
  list_generator<Gen> list_of(const Gen& gen) {
    return list_generator<Gen>(gen);
  }

  template <typename T, typename Gen = generator<T>>
  list_generator<Gen> list_of() {
    return list_of(Gen());
  }

  template <typename T>
  class generator<std::vector<T>> : public list_generator<generator<T>> {};

  /* Ordered list combinator. */

  namespace detail {

    struct sorter {
      template <typename T>
      std::vector<T> operator() (std::vector<T>&& a, size_t) {
        std::sort(a.begin(), a.end());
        return a;
      }
    };

  }

  template <typename Gen>
  detail::mapped_generator<detail::sorter, list_generator<Gen>>
  ordered_list(const Gen& gen) {
    return map(detail::sorter(), list_of(gen));
  }

  template <typename T, typename Gen = generator<T>>
  detail::mapped_generator<detail::sorter, list_generator<Gen>>
  ordered_list() {
    return ordered_list(Gen());
  }

  /* Generic type generator (by construction). */

  template <typename T, typename... Gens>
  class cons_generator {
    private:
      std::tuple<Gens...> gens;

    public:
      cons_generator() :
        gens(Gens()...) {}

      cons_generator(const Gens&... gens) :
        gens(gens...) {}

      typedef T result_type;

      result_type operator() (size_t size = 0) {
        return autocheck::generate<result_type>(gens, (size > 0) ? (size - 1) : size);
      }
  };

  template <typename T, typename... Gens>
  cons_generator<T, Gens...> cons(const Gens&... gens) {
    return cons_generator<T, Gens...>(gens...);
  }

  template <typename T, typename... Args>
  cons_generator<T, generator<Args>...> cons() {
    return cons_generator<T, generator<Args>...>();
  }

}

#endif

<|endoftext|>


<commit_before>#pragma once

#include "blackhole/sink.hpp"

namespace blackhole {

class config_t;

template<typename>
struct factory;

}  // namespace blackhole

namespace blackhole {
namespace sink {

/// Null sink implementation that drops all incoming events.
class null_t : public sink_t {
public:
    auto filter(const record_t& record) -> bool;
    auto execute(const record_t& record, const string_view& formatted) -> void;
};

}  // namespace sink

template<>
struct factory<sink::null_t> {
    static auto from(const config_t& config) -> sink::null_t;
};

}  // namespace blackhole
<commit_msg>docs(sink/null): add docs<commit_after>#pragma once

#include "blackhole/sink.hpp"

namespace blackhole {

class config_t;

template<typename>
struct factory;

}  // namespace blackhole

namespace blackhole {
namespace sink {

/// A null sink merely exists, it never outputs a message to any device.
///
/// This class exists primarily for benchmarking reasons to measure the entire logging processing
/// pipeline. It never fails and never throws, because it does nothing.
///
/// All methods of this class are thread safe.
class null_t : public sink_t {
public:
    /// Returns `false` regardless of a log record value, causing any log event to be dropped.
    auto filter(const record_t& record) -> bool;

    /// Drops any incoming log event.
    auto execute(const record_t& record, const string_view& formatted) -> void;
};

}  // namespace sink

template<>
struct factory<sink::null_t> {
    static auto from(const config_t& config) -> sink::null_t;
};

}  // namespace blackhole
<|endoftext|>