Commit d0231035 authored by Justin Carpentier's avatar Justin Carpentier Committed by Pierre Fernbach
Browse files

Initial commit

parents
[submodule "jrl-cmakemodules"]
path = jrl-cmakemodules
url = git://github.com/jrl-umi3218/jrl-cmakemodules.git
branch = master
# Copyright (c) 2015-2018, CNRS
# Authors: Justin Carpentier <jcarpent@laas.fr>
# Simplified BSD license :
#Redistribution and use in source and binary forms, with or without modification,
#are permitted provided that the following conditions are met:
#
#1. Redistributions of source code must retain the above copyright notice,
#this list of conditions and the following disclaimer.
#
#2. Redistributions in binary form must reproduce the above copyright notice,
#this list of conditions and the following disclaimer in the documentation
#and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
#OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
INCLUDE(cmake/base.cmake)
INCLUDE(cmake/boost.cmake)
INCLUDE(cmake/eigen.cmake)
INCLUDE(cmake/python.cmake)
INCLUDE(cmake/ide.cmake)
SET(PROJECT_NAME locomote)
SET(PROJECT_DESCRIPTION "Multi-contact locomotion for multi-body systems")
SET(PROJECT_URL "TODO")
OPTION(INSTALL_DOCUMENTATION "Generate and install the documentation" FALSE)
SET(DOXYGEN_USE_MATHJAX YES)
IF(APPLE)
SET(CMAKE_MACOSX_RPATH TRUE)
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
endif("${isSystemDir}" STREQUAL "-1")
ENDIF(APPLE)
# Disable -Werror on Unix for now.
SET(CXX_DISABLE_WERROR True)
SET(CMAKE_VERBOSE_MAKEFILE True)
SETUP_PROJECT()
IF(WIN32)
SET(LINK copy_if_different)
ELSE(WIN32)
SET(LINK create_symlink)
ENDIF(WIN32)
# --- OPTIONS ----------------------------------------
OPTION (BUILD_PYTHON_INTERFACE "Build the python binding" ON)
OPTION (BUILD_UNIT_TESTS "Build the unitary tests" ON)
# ----------------------------------------------------
# --- DEPENDANCIES -----------------------------------
# ----------------------------------------------------
ADD_REQUIRED_DEPENDENCY("eigen3 >= 3.0.5")
ADD_REQUIRED_DEPENDENCY("pinocchio >= 1.2.0")
SET(BOOST_COMPONENTS unit_test_framework serialization)
IF(BUILD_PYTHON_INTERFACE)
ADD_COMPILE_DEPENDENCY("eigenpy >= 1.3.1")
SET(BOOST_COMPONENTS ${BOOST_COMPONENTS} python)
FINDPYTHON(2.7 EXACT REQUIRED)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIRS})
ENDIF(BUILD_PYTHON_INTERFACE)
SEARCH_FOR_BOOST()
# Path to boost headers
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
# ----------------------------------------------------
# --- INCLUDE ----------------------------------------
# ----------------------------------------------------
SET(${PROJECT_NAME}_MATH_HEADERS
include/locomote/math/cumsum.hpp
include/locomote/math/factorial.hpp
include/locomote/math/nrand.hpp
include/locomote/math/search.hpp
)
SET(${PROJECT_NAME}_GEOMETRY_HEADERS
include/locomote/geometry/fwd.hpp
include/locomote/geometry/linear-cone.hpp
include/locomote/geometry/second-order-cone.hpp
include/locomote/geometry/ellipsoid.hpp
)
SET(${PROJECT_NAME}_SERIALIZATION_HEADERS
include/locomote/serialization/eigen-matrix.hpp
include/locomote/serialization/aligned-vector.hpp
include/locomote/serialization/spatial.hpp
include/locomote/serialization/fwd.hpp
include/locomote/serialization/xml.hpp
include/locomote/serialization/archive.hpp
)
SET(${PROJECT_NAME}_SCENARIO_HEADERS
include/locomote/scenario/fwd.hpp
include/locomote/scenario/contact-sequence.hpp
include/locomote/scenario/contact-phase.hpp
include/locomote/scenario/contact-patch.hpp
include/locomote/scenario/contact-phase-humanoid.hpp
include/locomote/scenario/constraint.hpp
include/locomote/scenario/constraint-gmm.hpp
include/locomote/scenario/constraint-soc.hpp
include/locomote/scenario/contact-constraint.hpp
include/locomote/scenario/contact-constraint-planar.hpp
include/locomote/scenario/contact-model-planar.hpp
include/locomote/scenario/ms-interval.hpp
)
SET(${PROJECT_NAME}_TRAJECTORIES_HEADERS
include/locomote/trajectories/fwd.hpp
include/locomote/trajectories/cubic-hermite-spline.hpp
)
SET(${PROJECT_NAME}_CONTAINER_HEADERS
include/locomote/container/ref.hpp
)
SET(HEADERS
${${PROJECT_NAME}_MATH_HEADERS}
${${PROJECT_NAME}_GEOMETRY_HEADERS}
${${PROJECT_NAME}_SERIALIZATION_HEADERS}
${${PROJECT_NAME}_SCENARIO_HEADERS}
${${PROJECT_NAME}_TRAJECTORIES_HEADERS}
${${PROJECT_NAME}_CONTAINER_HEADERS}
)
LIST(REMOVE_DUPLICATES HEADERS)
#MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/math")
#MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/geometry")
#MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/stats")
#MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/serialization")
#MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/scenario")
#MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/muscod")
#MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/model")
SET(HEADERS_FULL_PATH "")
FOREACH(header ${HEADERS})
LIST(APPEND HEADERS_FULL_PATH "${CMAKE_SOURCE_DIR}/${header}")
GET_FILENAME_COMPONENT(headerName ${header} NAME)
GET_FILENAME_COMPONENT(headerPath ${header} PATH)
INSTALL(FILES ${${PROJECT_NAME}_SOURCE_DIR}/${header}
DESTINATION ${CMAKE_INSTALL_PREFIX}/${headerPath}
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE)
ENDFOREACH(header ${HEADERS})
# --- BINDINGS ----------------------------------------------------------------
ADD_SUBDIRECTORY(bindings)
# --- UNIT TESTS ---------------------------------------------------------------
ADD_SUBDIRECTORY(unittest)
# --- PACKAGING ----------------------------------------------------------------
PKG_CONFIG_APPEND_LIBS(${PROJECT_NAME})
PKG_CONFIG_APPEND_BOOST_LIBS(serialization)
SETUP_PROJECT_FINALIZE()
# Copyright (c) 2015-2018, CNRS
# Authors: Justin Carpentier <jcarpent@laas.fr>
# Simplified BSD license :
#Redistribution and use in source and binary forms, with or without modification,
#are permitted provided that the following conditions are met:
#
#1. Redistributions of source code must retain the above copyright notice,
#this list of conditions and the following disclaimer.
#
#2. Redistributions in binary form must reproduce the above copyright notice,
#this list of conditions and the following disclaimer in the documentation
#and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
#OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ADD_SUBDIRECTORY(python)
# Copyright (c) 2015-2018, CNRS
# Authors: Justin Carpentier <jcarpent@laas.fr>
# Simplified BSD license :
#Redistribution and use in source and binary forms, with or without modification,
#are permitted provided that the following conditions are met:
#
#1. Redistributions of source code must retain the above copyright notice,
#this list of conditions and the following disclaimer.
#
#2. Redistributions in binary form must reproduce the above copyright notice,
#this list of conditions and the following disclaimer in the documentation
#and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
#OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IF(BUILD_PYTHON_INTERFACE)
SET(${PROJECT_NAME}_PYTHON_HEADERS
fwd.hpp
geometry/ellipsoid.hpp
geometry/linear-cone.hpp
geometry/second-order-cone.hpp
geometry/expose-geometry.hpp
serialization/archive.hpp
scenario/expose-scenario.hpp
scenario/contact-patch.hpp
scenario/contact-model-planar.hpp
scenario/contact-phase.hpp
scenario/contact-phase-humanoid.hpp
scenario/contact-sequence.hpp
scenario/enums.hpp
scenario/ms-interval.hpp
container/array.hpp
container/visitor.hpp
container/reference-wrapper.hpp
utils/base.hpp
utils/printable.hpp
trajectories/expose-trajectories.hpp
trajectories/cubic-hermite-spline.hpp
)
SET(${PROJECT_NAME}_PYTHON_SOURCES
module.cpp
geometry/ellipsoid.cpp
geometry/linear-cone.cpp
geometry/second-order-cone.cpp
scenario/contact-model.cpp
scenario/contact-patch.cpp
scenario/contact-phase.cpp
scenario/contact-sequence.cpp
scenario/enums.cpp
trajectories/trajectories.cpp
)
LIST(APPEND HEADERS ${${PROJECT_NAME}_PYTHON_HEADERS})
LIST(REMOVE_DUPLICATES HEADERS)
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/lib/python/${PROJECT_NAME}")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/bindings/python")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/bindings/python/geometry")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/bindings/python/scenario")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/bindings/python/serialization")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/bindings/python/container")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/bindings/python/utils")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/bindings/python/trajectories")
FOREACH(header ${${PROJECT_NAME}_PYTHON_HEADERS})
GET_FILENAME_COMPONENT(headerName ${header} NAME)
GET_FILENAME_COMPONENT(headerPath ${header} PATH)
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E ${LINK}
${${PROJECT_NAME}_SOURCE_DIR}/bindings/python/${header}
${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/bindings/python/${header})
INSTALL(FILES ${${PROJECT_NAME}_SOURCE_DIR}/bindings/python/${header}
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}/bindings/python
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE)
ENDFOREACH(header)
# --- PyWrap library --- #
SET(PYWRAP ${PROJECT_NAME}_pywrap)
ADD_LIBRARY(${PYWRAP} SHARED ${${PROJECT_NAME}_PYTHON_SOURCES} ${${PROJECT_NAME}_PYTHON_HEADERS})
ADD_HEADER_GROUP(${PROJECT_NAME}_PYTHON_HEADERS)
ADD_SOURCE_GROUP(${PROJECT_NAME}_PYTHON_SOURCES)
PKG_CONFIG_USE_DEPENDENCY(${PYWRAP} eigenpy)
PKG_CONFIG_USE_DEPENDENCY(${PYWRAP} pinocchio)
TARGET_LINK_LIBRARIES(${PYWRAP} ${Boost_SERIALIZATION_LIBRARIES})
TARGET_LINK_BOOST_PYTHON(${PYWRAP})
IF(APPLE)
# We need to change the extension for python bindings
SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES SUFFIX ".so")
ENDIF(APPLE)
SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/python/${PROJECT_NAME}")
INSTALL(FILES
"${CMAKE_BINARY_DIR}/lib/python/${PROJECT_NAME}/lib${PYWRAP}.so"
DESTINATION ${PYTHON_SITELIB}/${PROJECT_NAME})
# --- INSTALL SCRIPTS
SET(PYTHON_FILES
__init__.py
)
FOREACH(python ${PYTHON_FILES})
GET_FILENAME_COMPONENT(pythonFile ${python} NAME)
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E ${LINK}
${${PROJECT_NAME}_SOURCE_DIR}/bindings/python/${python}
${${PROJECT_NAME}_BINARY_DIR}/lib/python/${PROJECT_NAME}/${pythonFile})
# Tag pyc file as generated.
SET_SOURCE_FILES_PROPERTIES(
"${${PROJECT_NAME}_BINARY_DIR}/lib/python/${PROJECT_NAME}/${pythonFile}c"
PROPERTIES GENERATED TRUE)
EXECUTE_PROCESS(COMMAND
${PYTHON_EXECUTABLE} -m py_compile
${${PROJECT_NAME}_BINARY_DIR}/lib/python/${PROJECT_NAME}/${pythonFile})
# Clean generated files.
SET_PROPERTY(
DIRECTORY APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
"${${PROJECT_NAME}_BINARY_DIR}/lib/python/${PROJECT_NAME}/${pythonFile}c")
INSTALL(FILES
"${${PROJECT_NAME}_SOURCE_DIR}/bindings/python/${python}"
"${${PROJECT_NAME}_BINARY_DIR}/lib/python/${PROJECT_NAME}/${pythonFile}c"
DESTINATION ${PYTHON_SITELIB}/${PROJECT_NAME})
ENDFOREACH(python)
ENDIF(BUILD_PYTHON_INTERFACE)
# Copyright (c) 2015-2018, CNRS
# Authors: Justin Carpentier <jcarpent@laas.fr>
# Simplified BSD license :
#Redistribution and use in source and binary forms, with or without modification,
#are permitted provided that the following conditions are met:
#
#1. Redistributions of source code must retain the above copyright notice,
#this list of conditions and the following disclaimer.
#
#2. Redistributions in binary form must reproduce the above copyright notice,
#this list of conditions and the following disclaimer in the documentation
#and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
#OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import liblocomote_pywrap as locomote
from liblocomote_pywrap import *
import numpy as np
// Copyright (c) 2015-2018, CNRS
// Authors: Justin Carpentier <jcarpent@laas.fr>
// Simplified BSD license :
//Redistribution and use in source and binary forms, with or without modification,
//are permitted provided that the following conditions are met:
//1. Redistributions of source code must retain the above copyright notice,
//this list of conditions and the following disclaimer.
//2. Redistributions in binary form must reproduce the above copyright notice,
//this list of conditions and the following disclaimer in the documentation
//and/or other materials provided with the distribution.
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
//OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
//OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
//WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
//OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef __locomote_python_container_array_hpp__
#define __locomote_python_container_array_hpp__
/// Credit : code adapted from http://stackoverflow.com/questions/18882089/wrapping-arrays-in-boost-python
#include <string>
#include <typeinfo>
#include <boost/python.hpp>
#include <boost/python/suite/indexing/indexing_suite.hpp>
namespace boost
{
namespace python
{
namespace bp = boost::python;
namespace details {
template <typename> struct array_trait;
/// @brief Type that proxies to an array.
template <typename T>
class array_proxy
{
public:
// Types
typedef T value_type;
typedef T* iterator;
typedef T& reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
/// @brief Empty constructor.
array_proxy()
: ptr_(0),
length_(0)
{}
/// @brief Construct with iterators.
template <typename Iterator>
array_proxy(Iterator begin, Iterator end)
: ptr_(&*begin),
length_(std::distance(begin, end))
{}
/// @brief Construct with start and size.
array_proxy(reference begin, std::size_t length)
: ptr_(&begin),
length_(length)
{}
// Iterator support.
iterator begin() { return ptr_; }
iterator end() { return ptr_ + length_; }
// Element access.
reference operator[](size_t i) { return ptr_[i]; }
// Capacity.
size_type size() { return length_; }
private:
T* ptr_;
std::size_t length_;
};
/// @brief Make an array_proxy.
template <typename T>
array_proxy<typename array_trait<T>::element_type>
make_array_proxy(T& array)
{
return array_proxy<typename array_trait<T>::element_type>(
array[0],
array_trait<T>::static_size);
}
/// @brief Policy type for referenced indexing, meeting the DerivedPolicies
/// requirement of bp::index_suite.
///
/// @note Requires Container to support:
/// - value_type and size_type types,
/// - value_type is default constructable and copyable,
/// - element access via operator[],
/// - Default constructable, iterator constructable,
/// - begin(), end(), and size() member functions
template <typename Container>
class ref_index_suite
: public bp::indexing_suite<Container, ref_index_suite<Container> >
{
public:
typedef typename Container::value_type data_type;
typedef typename Container::size_type index_type;
typedef typename Container::size_type size_type;
typedef typename Container::difference_type difference_type;
// Element access and manipulation.
/// @brief Get element from container.
static data_type&
get_item(Container & container, index_type index)
{
return container[index];
}
/// @brief Set element from container.
static void
set_item(Container & container, index_type index, const data_type& value)
{
container[index] = value;
}
/// @brief Reset index to default value.
static void
delete_item(Container & container, index_type index)
{
set_item(container, index, data_type());
};
// Slice support.
/// @brief Get slice from container.
///
/// @return Python object containing
static bp::object
get_slice(Container & container, index_type from, index_type to)
{
using bp::list;
if (from > to) return list();
// Return copy, as container only references its elements.
list list;
while (from != to) list.append(container[from++]);
return list;
};
/// @brief Set a slice in container with a given value.
static void
set_slice(Container & container, index_type from,
index_type to, const data_type& value
)
{
// If range is invalid, return early.
if (from > to) return;
// Populate range with value.
while (from < to) container[from++] = value;
}
/// @brief Set a slice in container with another range.
template <class Iterator>
static void
set_slice(Container & container, index_type from,
index_type to, Iterator first, Iterator /*last*/
)
{
// If range is invalid, return early.
if (from > to) return;
// Populate range with other range.
while (from < to) container[from++] = *first++;
}
/// @brief Reset slice to default values.
static void
delete_slice(Container & container, index_type from, index_type to)
{
set_slice(container, from, to, data_type());
}
// Capacity.
/// @brief Get size of container.
static std::size_t
size(Container & container) { return container.size(); }
/// @brief Check if a value is within the container.
template <class T>
static bool
contains(Container & container, const T& value)
{
return std::find(container.begin(), container.end(), value)
!= container.end();
}
/// @brief Compare two indexes
static bool
compare_index(Container & /*container*/, index_type a, index_type b)
{
return a < b;
}
/// @brief Minimum index supported for container.
static index_type
get_min_index(Container & /*container*/)
{
return 0;
}
/// @brief Maximum index supported for container.
static index_type
get_max_index(Container & container)
{
return size(container);
}