1

I'm trying to use a boost matrix of fb_t, which is a relic object that represents element of finite field. Here is how fb_t is defined from the doc:

typedef uint64_t dig_t
typedef align dig_t fb_t[FB_DIGS+PADDING(FB_BYTES)/(FB_DIGIT/8)]

and here's my code:

#include <iostream>
#include <boost/numeric/ublas/matrix.hpp>

extern "C" {
#include <relic.h>
}
#include "relic_test.h"

using namespace std;
typedef boost::numeric::ublas::matrix<fb_t> matrix;

int main(void) {
    core_init();
    fb_param_set_any();
    fb_param_print();

    matrix mat(2,2);

   core_clean();
   return 0;
}

I got the following error:

Compiling: main.cpp
In file included from /usr/include/boost/numeric/ublas/vector.hpp:19:0,
                 from /usr/include/boost/numeric/ublas/matrix.hpp:16,
                 from /home/Foo/main.cpp:2:
/usr/include/boost/numeric/ublas/storage.hpp: In instantiation of ‘boost::numeric::ublas::unbounded_array<T, ALLOC>::unbounded_array(boost::numeric::ublas::unbounded_array<T, ALLOC>::size_type, const ALLOC&) [with T = unsigned int [4]; ALLOC = std::allocator<unsigned int [4]>; boost::numeric::ublas::unbounded_array<T, ALLOC>::size_type = unsigned int]’:
/usr/include/boost/numeric/ublas/matrix.hpp:131:92:   required from ‘boost::numeric::ublas::matrix<T, L, A>::matrix(boost::numeric::ublas::matrix<T, L, A>::size_type, boost::numeric::ublas::matrix<T, L, A>::size_type) [with T = unsigned int [4]; L = boost::numeric::ublas::basic_row_major<>; A = boost::numeric::ublas::unbounded_array<unsigned int [4], std::allocator<unsigned int [4]> >; boost::numeric::ublas::matrix<T, L, A>::size_type = unsigned int]’
/home/Foo/main.cpp:21:19:   required from here
/usr/include/boost/numeric/ublas/storage.hpp:71:23: error: functional cast to array type ‘boost::numeric::ublas::unbounded_array<unsigned int [4], std::allocator<unsigned int [4]> >::value_type {aka unsigned int [4]}’
/usr/include/boost/numeric/ublas/storage.hpp: In instantiation of ‘static void boost::numeric::ublas::unbounded_array<T, ALLOC>::iterator_destroy(T*&) [with T = unsigned int [4]; ALLOC = std::allocator<unsigned int [4]>; boost::numeric::ublas::unbounded_array<T, ALLOC>::iterator = unsigned int (*)[4]]’:
/usr/include/boost/numeric/ublas/storage.hpp:106:25:   required from ‘boost::numeric::ublas::unbounded_array<T, ALLOC>::~unbounded_array() [with T = unsigned int [4]; ALLOC = std::allocator<unsigned int [4]>]’
/usr/include/boost/numeric/ublas/matrix.hpp:90:11:   required from here
/usr/include/boost/numeric/ublas/storage.hpp:290:13: error: request for member ‘~boost::numeric::ublas::unbounded_array<unsigned int [4], std::allocator<unsigned int [4]> >::value_type’ in ‘* i’, which is of non-class type ‘unsigned int [4]’

I'm not quite sure what the error message is about. Any idea?

nullgraph
  • 297
  • 1
  • 6
  • 17
  • I don't think `boost::ublas` supports arrays as value types. The error message makes me think it's trying to do something like `ValueType(value)`, which isn't valid if `ValueType` is an array because arrays cannot be copied. – David Brown Sep 03 '13 at 20:27
  • @DavidBrown I suspected something similar. Do you have any suggestion on how to fix this? – nullgraph Sep 03 '13 at 20:37
  • You could wrap `fb_t` in a class that constructs and copies it correctly. Or you could replace it with `std::array`. – David Brown Sep 03 '13 at 20:40
  • @DavidBrown Exactly what I was afraid of. In my case, writing my own matrix class seems to be less painful. Thanks for the response. If you repost it as an answer, I'll accept it. – nullgraph Sep 03 '13 at 20:46

1 Answers1

2

I don't think boost::ublas supports arrays as value types. The error message is likely because arrays are not copyable. To get around this you could wrap fb_t in a class:

struct fb_t_wrapper {
    fb_t value;
};

Or use std::array

using fb_t_array = std::array<dig_t, FB_DIGS+PADDING(FB_BYTES)/(FB_DIGIT/8)>;
David Brown
  • 13,336
  • 4
  • 38
  • 55