Skip to content

Commit 0abb207

Browse files
authored
Merge pull request #91 from artivis/feature/appveyor
Add Appveyor CI - Visual Studio 15
2 parents 27c5d51 + 57522de commit 0abb207

22 files changed

+231
-117
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# manif
22
## A small header-only library for Lie theory.
33

4-
[![Build Status](https://travis-ci.com/artivis/manif.svg?branch=devel)](https://travis-ci.com/artivis/manif)
4+
[![travis](https://travis-ci.com/artivis/manif.svg?branch=devel)](https://travis-ci.com/artivis/manif)
5+
[![appveyor](https://ci.appveyor.com/api/projects/status/l0q7b0shhonvejrd?svg=true)](https://ci.appveyor.com/project/artivis/manif)
56
[![Documentation](https://codedocs.xyz/artivis/manif.svg)](https://codedocs.xyz/artivis/manif/)
67
[![codecov](https://codecov.io/gh/artivis/manif/branch/devel/graph/badge.svg)](https://codecov.io/gh/artivis/manif)
78
![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)

appveyor.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
branches:
2+
only:
3+
- master
4+
- devel
5+
6+
skip_commits:
7+
files:
8+
- '**/.doxygen.txt'
9+
- '**/.gitignore'
10+
- '**/.travis.yml'
11+
- '**/*.md'
12+
- '**/LICENSE.txt'
13+
14+
os: Visual Studio 2015
15+
16+
environment:
17+
matrix:
18+
# @TODO Does not compile on VS14
19+
# - generator: "Visual Studio 14 Win64"
20+
# configuration: Release
21+
# build_tests: ON
22+
# build_ceres_tests: OFF
23+
# build_examples: ON
24+
25+
- generator: "Visual Studio 15 Win64"
26+
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
27+
configuration: Release
28+
build_tests: ON
29+
build_ceres_tests: OFF
30+
build_examples: ON
31+
32+
# @TODO Disabled until Ceres install is fixed
33+
# - generator: "Visual Studio 15 Win64"
34+
# APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
35+
# configuration: Release
36+
# build_tests: ON
37+
# build_ceres_tests: ON
38+
# build_examples: ON
39+
40+
clone_folder: c:\projects\manif
41+
42+
build:
43+
project: c:\projects\manif\build\manif.sln
44+
45+
install:
46+
- ps: |
47+
Write-Output "Generator: $env:generator"
48+
Write-Output "Env:Configuation: $env:configuration"
49+
if (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) {
50+
Write-Output "This is a pull request build"
51+
}
52+
53+
# Get Eigen 3.3-beta1
54+
- ps: wget -O eigen3.zip http://bitbucket.org/eigen/eigen/get/3.3-beta1.zip
55+
- cmd: 7z x eigen3.zip -o"C:\projects" -y > nul
56+
# - cmd: $env:CMAKE_INCLUDE_PATH = "C:\projects\eigen-eigen-ce5a455b34c0;$env:CMAKE_INCLUDE_PATH"
57+
58+
build_script:
59+
# Install Ceres.
60+
# @TODO does not work atm, Ceres does not find Eigen
61+
- ps: |
62+
if ($env:build_ceres_tests -eq "ON")
63+
{
64+
Write-Output "Building Ceres."
65+
cd c:\projects
66+
git clone --branch=1.14.0 --single-branch git://github.com/ceres-solver/ceres-solver.git ceres-solver
67+
cd ceres-solver
68+
md _build
69+
cd _build
70+
$eigen_include = "-DEIGEN3_INCLUDE_DIR=C:\projects\eigen-eigen-ce5a455b34c0"
71+
cmake -G "$env:generator" $eigen_include -DMINIGLOG=ON -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF ..
72+
cmake --build . --config $env:configuration --target install
73+
}
74+
75+
# Build manif
76+
- ps: |
77+
cd c:\projects\manif
78+
md _build
79+
cd _build
80+
$btests = "-DBUILD_TESTING=$env:build_tests"
81+
$bexamples = "-DBUILD_EXAMPLES=$env:build_examples"
82+
$eigen_include = "-DEIGEN3_INCLUDE_DIR=C:\projects\eigen-eigen-ce5a455b34c0"
83+
cmake -G "$env:generator" $eigen_include $btests $bexamples ..
84+
cmake --build . --config $env:configuration
85+
86+
test_script:
87+
- ps: ctest -VV -C $env:configuration --output-on-failure
88+
89+
notifications:
90+
- provider: Email
91+
92+
on_build_success: false
93+
on_build_failure: true
94+
on_build_status_changed: false

include/manif/algorithms/decasteljau.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,17 @@ decasteljau(const std::vector<LieGroup>& trajectory,
4141
"k_interp must be greater than zero!");
4242

4343
// Number of connected, non-overlapping segments
44-
const unsigned int n_segments =
45-
std::floor(double(trajectory.size()-degree)/(degree-1)+1);
44+
const unsigned int n_segments = static_cast<unsigned int>(
45+
std::floor(double(trajectory.size()-degree)/double((degree-1)+1))
46+
);
4647

4748
std::vector<std::vector<const LieGroup*>> segments_control_points;
4849
for (unsigned int t=0; t<n_segments; ++t)
4950
{
5051
segments_control_points.emplace_back(std::vector<const LieGroup*>());
5152

5253
// Retrieve control points of the current segment
53-
for (int n=0; n<degree; ++n)
54+
for (unsigned int n=0; n<degree; ++n)
5455
{
5556
segments_control_points.back().push_back( &trajectory[t*(degree-1)+n] );
5657
}
@@ -59,30 +60,30 @@ decasteljau(const std::vector<LieGroup>& trajectory,
5960
// Close the curve if there are left-over points
6061
if (closed_curve && (n_segments*(degree-1)) <= trajectory.size()-1)
6162
{
62-
const int last_pts_idx = n_segments*(degree-1);
63-
const int left_over = trajectory.size()-1-last_pts_idx;
63+
const unsigned int last_pts_idx = n_segments*(degree-1);
64+
const unsigned int left_over = trajectory.size()-1-last_pts_idx;
6465
segments_control_points.emplace_back(std::vector<const LieGroup*>());
6566

6667
// Get the left-over points
67-
for (int p=last_pts_idx; p<trajectory.size(); ++p)
68+
for (unsigned int p=last_pts_idx; p<trajectory.size(); ++p)
6869
{
6970
segments_control_points.back().push_back( &trajectory[p] );
7071
}
7172
// Add a extra points from the beginning of the trajectory
72-
for (int p=0; p<degree-left_over-1; ++p)
73+
for (unsigned int p=0; p<degree-left_over-1; ++p)
7374
{
7475
segments_control_points.back().push_back( &trajectory[p] );
7576
}
7677
}
7778

78-
const int segment_k_interp = (degree == 2) ?
79+
const unsigned int segment_k_interp = (degree == 2) ?
7980
k_interp : k_interp * degree;
8081

8182
// Actual curve fitting
8283
std::vector<LieGroup> curve;
8384
for (unsigned int s=0; s<segments_control_points.size(); ++s)
8485
{
85-
for (int t=1; t<=segment_k_interp; ++t)
86+
for (unsigned int t=1; t<=segment_k_interp; ++t)
8687
{
8788
// t in [0,1]
8889
const double t_01 = static_cast<double>(t)/(segment_k_interp);
@@ -94,9 +95,9 @@ decasteljau(const std::vector<LieGroup>& trajectory,
9495

9596
// recursive chunk of the algo,
9697
// compute tmp control points.
97-
for (int i=0; i<degree-1; ++i)
98+
for (unsigned int i=0; i<degree-1; ++i)
9899
{
99-
for (int q=0; q<Qs.size()-1; ++q)
100+
for (unsigned int q=0; q<Qs.size()-1; ++q)
100101
{
101102
Qs_tmp.push_back( Qs[q].rplus(Qs[q+1].rminus(Qs[q]) * t_01) );
102103
}

include/manif/constants.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ namespace internal {
1414
/**
1515
* Constexpr Newton-Raphson iterative algorithm for the sqrt aprrox.
1616
*/
17-
double constexpr sqrtNewtonRaphson(double x, double curr, double prev)
17+
template <typename T>
18+
T constexpr sqrtNewtonRaphson(T x, T curr, T prev)
1819
{
1920
return curr == prev
2021
? curr
21-
: sqrtNewtonRaphson(x, 0.5 * (curr + x / curr), curr);
22+
: sqrtNewtonRaphson(x, T(0.5) * (curr + x / curr), curr);
2223
}
2324

2425
/**
@@ -30,11 +31,12 @@ double constexpr sqrtNewtonRaphson(double x, double curr, double prev)
3031
*
3132
* credits : https://stackoverflow.com/a/34134071/9709397
3233
*/
33-
double constexpr csqrt(double x)
34+
template <typename T>
35+
T constexpr csqrt(T x)
3436
{
35-
return x >= 0 && x < std::numeric_limits<double>::infinity()
36-
? sqrtNewtonRaphson(x, x, 0)
37-
: std::numeric_limits<double>::quiet_NaN();
37+
return x >= T(0) && x < std::numeric_limits<T>::infinity()
38+
? sqrtNewtonRaphson(x, x, T(0))
39+
: std::numeric_limits<T>::quiet_NaN();
3840
}
3941

4042
} /* namespace internal */

include/manif/impl/eigen.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@
5454
// Define some custom assert macros
5555

5656
#define assert_rows_dim(x, dim) \
57-
static_assert(static_cast<int>(std::decay<decltype(x)>::type::RowsAtCompileTime) == dim or \
57+
static_assert(static_cast<int>(std::decay<decltype(x)>::type::RowsAtCompileTime) == dim || \
5858
std::decay<decltype(x)>::type::RowsAtCompileTime == Eigen::Dynamic, \
5959
"x.rows != "#dim" ."); \
6060
assert(x.rows() == dim && "x.cols != "#dim" .");
6161

6262
#define assert_cols_dim(x, dim) \
63-
static_assert(static_cast<int>(std::decay<decltype(x)>::type::ColsAtCompileTime) == dim or \
63+
static_assert(static_cast<int>(std::decay<decltype(x)>::type::ColsAtCompileTime) == dim || \
6464
std::decay<decltype(x)>::type::ColsAtCompileTime == Eigen::Dynamic, \
6565
"x.cols != "#dim" ."); \
6666
assert(x.cols() == dim && "x.rows != "#dim" .");
@@ -71,20 +71,20 @@
7171

7272
#define assert_dim_eq(l,r) \
7373
static_assert(static_cast<int>(std::decay<decltype(l)>::type::ColsAtCompileTime) == \
74-
static_cast<int>(std::decay<decltype(r)>::type::ColsAtCompileTime) or \
75-
std::decay<decltype(l)>::type::ColsAtCompileTime == Eigen::Dynamic or \
74+
static_cast<int>(std::decay<decltype(r)>::type::ColsAtCompileTime) || \
75+
std::decay<decltype(l)>::type::ColsAtCompileTime == Eigen::Dynamic || \
7676
std::decay<decltype(r)>::type::ColsAtCompileTime == Eigen::Dynamic, \
7777
"lhs.cols != rhs.cols !"); \
7878
static_assert(static_cast<int>(std::decay<decltype(l)>::type::RowsAtCompileTime) == \
79-
static_cast<int>(std::decay<decltype(r)>::type::RowsAtCompileTime) or \
80-
std::decay<decltype(l)>::type::RowsAtCompileTime == Eigen::Dynamic or \
79+
static_cast<int>(std::decay<decltype(r)>::type::RowsAtCompileTime) || \
80+
std::decay<decltype(l)>::type::RowsAtCompileTime == Eigen::Dynamic || \
8181
std::decay<decltype(r)>::type::RowsAtCompileTime == Eigen::Dynamic, \
8282
"lhs.rows != rhs.rows !"); \
8383
assert(l.rows() == r.rows() && "lhs.rows != rhs.rows !"); \
8484
assert(l.cols() == r.cols() && "lhs.cols != rhs.cols !"); \
8585

8686
#define assert_is_vector(x) \
87-
static_assert(std::decay<decltype(x)>::type::ColsAtCompileTime == 1 or \
87+
static_assert(std::decay<decltype(x)>::type::ColsAtCompileTime == 1 || \
8888
std::decay<decltype(x)>::type::ColsAtCompileTime == Eigen::Dynamic, \
8989
"Expected a vector !"); \
9090
assert(x.cols() == 1 && "Expected a vector !"); \
@@ -94,7 +94,7 @@
9494
assert_rows_dim(x, dim);
9595

9696
#define assert_is_colmajor_vector(x) \
97-
static_assert(std::decay<decltype(x)>::type::RowsAtCompileTime == 1 or \
97+
static_assert(std::decay<decltype(x)>::type::RowsAtCompileTime == 1 || \
9898
std::decay<decltype(x)>::type::RowsAtCompileTime == Eigen::Dynamic, \
9999
"Expected a column-major vector !"); \
100100
assert(x.rows() == 1 && "Expected a column-major vector !"); \
@@ -106,6 +106,12 @@
106106
namespace manif {
107107
namespace internal {
108108

109+
template< class Base, class Derived >
110+
constexpr bool is_base_of_v()
111+
{
112+
return std::is_base_of<Base, Derived>::value;
113+
}
114+
109115
/**
110116
* @brief traitscast specialization that come handy when writing thing like
111117
* using Matrix3f = typename traitscast<Matrix3d, float>::cast;
@@ -140,9 +146,8 @@ skew(const _Scalar v)
140146
* | -v(1) +v(0) 0 |
141147
*/
142148
template <typename _Derived>
143-
typename std::enable_if<std::is_base_of<Eigen::MatrixBase<_Derived>,
144-
_Derived>::value and
145-
_Derived::RowsAtCompileTime == 3,
149+
typename std::enable_if<(internal::is_base_of_v<Eigen::MatrixBase<_Derived>, _Derived>()
150+
&& _Derived::RowsAtCompileTime == 3),
146151
Eigen::Matrix<typename _Derived::Scalar, 3, 3>>::type
147152
skew(const Eigen::MatrixBase<_Derived>& v)
148153
{

include/manif/impl/macro.h

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,49 +18,70 @@ struct invalid_argument : std::invalid_argument
1818
};
1919

2020
namespace detail {
21+
2122
template <typename E, typename... Args>
2223
void
23-
__attribute__(( noinline, cold, noreturn )) raise(Args&&... args)
24+
#if defined(__GNUC__) || defined(__clang__)
25+
__attribute__(( noinline, cold, noreturn ))
26+
#elif defined(_MSC_VER)
27+
__declspec( noinline, noreturn )
28+
#else
29+
// nothing
30+
#endif
31+
raise(Args&&... args)
2432
{
2533
throw E(std::forward<Args>(args)...);
2634
}
2735
} /* namespace detail */
2836
} /* namespace manif */
2937

38+
// gcc expands __VA_ARGS___ before passing it into the macro.
39+
// Visual Studio expands __VA_ARGS__ after passing it.
40+
// This macro is a workaround to support both
41+
#define __MANIF_EXPAND(x) x
42+
43+
#if defined(__cplusplus) && defined(__has_cpp_attribute)
44+
#define __MANIF_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
45+
#else
46+
#define __MANIF_HAVE_CPP_ATTRIBUTE(x) 0
47+
#endif
48+
3049
#define __MANIF_THROW_EXCEPT(msg, except) manif::detail::raise<except>(msg);
31-
#define __MANIF_THROW(msg) __MANIF_THROW_EXCEPT(msg, runtime_error)
50+
#define __MANIF_THROW(msg) __MANIF_THROW_EXCEPT(msg, manif::runtime_error)
3251

3352
#define __MANIF_GET_MACRO_2(_1,_2,NAME,...) NAME
3453

3554
#define MANIF_THROW(...) \
55+
__MANIF_EXPAND( \
3656
__MANIF_GET_MACRO_2(__VA_ARGS__, \
3757
__MANIF_THROW_EXCEPT, \
38-
__MANIF_THROW)(__VA_ARGS__)
39-
58+
__MANIF_THROW)(__VA_ARGS__) )
4059

4160
#define __MANIF_CHECK_MSG_EXCEPT(cond, msg, except) \
42-
if (!(cond)) MANIF_THROW(msg, except);
61+
if (!(cond)) {MANIF_THROW(msg, except);}
4362
#define __MANIF_CHECK_MSG(cond, msg) \
44-
__MANIF_CHECK_MSG_EXCEPT(cond, msg, runtime_error)
63+
__MANIF_CHECK_MSG_EXCEPT(cond, msg, manif::runtime_error)
4564
#define __MANIF_CHECK(cond) \
46-
__MANIF_CHECK_MSG_EXCEPT(cond, "Condition: '"#cond"' failed!", runtime_error)
65+
__MANIF_CHECK_MSG_EXCEPT(cond, "Condition: '"#cond"' failed!", manif::runtime_error)
4766

4867
#define __MANIF_GET_MACRO_3(_1,_2,_3,NAME,...) NAME
4968

5069
#define MANIF_CHECK(...) \
70+
__MANIF_EXPAND( \
5171
__MANIF_GET_MACRO_3(__VA_ARGS__, \
5272
__MANIF_CHECK_MSG_EXCEPT, \
5373
__MANIF_CHECK_MSG, \
54-
__MANIF_CHECK)(__VA_ARGS__)
55-
74+
__MANIF_CHECK)(__VA_ARGS__) )
5675

5776
#define MANIF_NOT_IMPLEMENTED_YET \
5877
MANIF_THROW("Not implemented yet !");
5978

60-
#if defined(__cplusplus) && (__cplusplus >= 201402L)
79+
#if defined(__cplusplus) && (__cplusplus >= 201402L) && __MANIF_HAVE_CPP_ATTRIBUTE(deprecated)
6180
#define MANIF_DEPRECATED [[deprecated]]
6281
#elif defined(__GNUC__) || defined(__clang__)
6382
#define MANIF_DEPRECATED __attribute__((deprecated))
83+
#elif defined(_MSC_VER)
84+
#define MANIF_DEPRECATED __declspec(deprecated)
6485
#else
6586
#pragma message("WARNING: Deprecation is disabled "\
6687
"-- the compiler is not supported.")

include/manif/impl/se2/SE2.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ struct SE2 : SE2Base<SE2<_Scalar>>
141141

142142
protected:
143143

144-
friend class LieGroupBase<SE2<Scalar>>;
144+
friend struct LieGroupBase<SE2<Scalar>>;
145145
DataType& coeffs_nonconst();
146146

147147
DataType data_;

include/manif/impl/se2/SE2_map.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class Map<manif::SE2<_Scalar>, 0>
5959

6060
protected:
6161

62-
friend class manif::LieGroupBase<Map<manif::SE2<_Scalar>, 0>>;
62+
friend struct manif::LieGroupBase<Map<manif::SE2<_Scalar>, 0>>;
6363
DataType& coeffs_nonconst() { return data_; }
6464

6565
DataType data_;

include/manif/impl/se3/SE3.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ struct SE3 : SE3Base<SE3<_Scalar>>
143143

144144
protected:
145145

146-
friend class LieGroupBase<SE3<Scalar>>;
146+
friend struct LieGroupBase<SE3<Scalar>>;
147147
DataType& coeffs_nonconst();
148148

149149
DataType data_;

include/manif/impl/se3/SE3_map.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class Map<manif::SE3<_Scalar>, 0>
5353

5454
protected:
5555

56-
friend class manif::LieGroupBase<Map<manif::SE3<_Scalar>, 0>>;
56+
friend struct manif::LieGroupBase<Map<manif::SE3<_Scalar>, 0>>;
5757
DataType& coeffs_nonconst() { return data_; }
5858

5959
DataType data_;

0 commit comments

Comments
 (0)