#include <stdio.h>
#include <stdlib.h>
#include <gsl/gsl_block.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_errno.h>

/* Block IO */
int mgsl_block_fwrite(const char *filename, const gsl_block *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_fread(const char *filename, gsl_block *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_fprintf(const char *filename, const gsl_block *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_fscanf(const char *filename, gsl_block *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_float_fwrite(const char *filename, const gsl_block_float *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_float_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_float_fread(const char *filename, gsl_block_float *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_float_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_float_fprintf(const char *filename, const gsl_block_float *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_float_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_float_fscanf(const char *filename, gsl_block_float *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_float_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_int_fwrite(const char *filename, const gsl_block_int *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_int_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_int_fread(const char *filename, gsl_block_int *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_int_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_int_fprintf(const char *filename, const gsl_block_int *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_int_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_int_fscanf(const char *filename, gsl_block_int *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_int_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_uint_fwrite(const char *filename, const gsl_block_uint *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_uint_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_uint_fread(const char *filename, gsl_block_uint *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_uint_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_uint_fprintf(const char *filename, const gsl_block_uint *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_uint_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_uint_fscanf(const char *filename, gsl_block_uint *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_uint_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_long_fwrite(const char *filename, const gsl_block_long *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_long_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_long_fread(const char *filename, gsl_block_long *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_long_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_long_fprintf(const char *filename, const gsl_block_long *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_long_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_long_fscanf(const char *filename, gsl_block_long *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_long_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_ulong_fwrite(const char *filename, const gsl_block_ulong *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_ulong_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_ulong_fread(const char *filename, gsl_block_ulong *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_ulong_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_ulong_fprintf(const char *filename, const gsl_block_ulong *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_ulong_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_ulong_fscanf(const char *filename, gsl_block_ulong *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_ulong_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_short_fwrite(const char *filename, const gsl_block_short *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_short_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_short_fread(const char *filename, gsl_block_short *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_short_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_short_fprintf(const char *filename, const gsl_block_short *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_short_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_short_fscanf(const char *filename, gsl_block_short *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_short_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_ushort_fwrite(const char *filename, const gsl_block_ushort *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_ushort_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_ushort_fread(const char *filename, gsl_block_ushort *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_ushort_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_ushort_fprintf(const char *filename, const gsl_block_ushort *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_ushort_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_ushort_fscanf(const char *filename, gsl_block_ushort *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_ushort_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_char_fwrite(const char *filename, const gsl_block_char *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_char_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_char_fread(const char *filename, gsl_block_char *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_char_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_char_fprintf(const char *filename, const gsl_block_char *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_char_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_char_fscanf(const char *filename, gsl_block_char *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_char_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_uchar_fwrite(const char *filename, const gsl_block_uchar *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_uchar_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_uchar_fread(const char *filename, gsl_block_uchar *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_uchar_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_uchar_fprintf(const char *filename, const gsl_block_uchar *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_uchar_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_uchar_fscanf(const char *filename, gsl_block_uchar *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_uchar_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_complex_fwrite(const char *filename, const gsl_block_complex *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_complex_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_complex_fread(const char *filename, gsl_block_complex *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_complex_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_complex_fprintf(const char *filename, const gsl_block_complex *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_complex_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_complex_fscanf(const char *filename, gsl_block_complex *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_complex_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_complex_float_fwrite(const char *filename, const gsl_block_complex_float *b)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_complex_float_fwrite(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_complex_float_fread(const char *filename, gsl_block_complex_float *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_complex_float_fread(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_complex_float_fprintf(const char *filename, const gsl_block_complex_float *b, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_block_complex_float_fprintf(fp, b, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_block_complex_float_fscanf(const char *filename, gsl_block_complex_float *b)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_block_complex_float_fscanf(fp, b) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

/* Vector IO */
int mgsl_vector_fwrite(const char *filename, const gsl_vector *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_fread(const char *filename, gsl_vector *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_fprintf(const char *filename, const gsl_vector *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_fscanf(const char *filename, gsl_vector *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_float_fwrite(const char *filename, const gsl_vector_float *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_float_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_float_fread(const char *filename, gsl_vector_float *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_float_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_float_fprintf(const char *filename, const gsl_vector_float *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_float_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_float_fscanf(const char *filename, gsl_vector_float *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_float_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_int_fwrite(const char *filename, const gsl_vector_int *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_int_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_int_fread(const char *filename, gsl_vector_int *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_int_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_int_fprintf(const char *filename, const gsl_vector_int *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_int_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_int_fscanf(const char *filename, gsl_vector_int *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_int_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_uint_fwrite(const char *filename, const gsl_vector_uint *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_uint_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_uint_fread(const char *filename, gsl_vector_uint *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_uint_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_uint_fprintf(const char *filename, const gsl_vector_uint *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_uint_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_uint_fscanf(const char *filename, gsl_vector_uint *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_uint_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_long_fwrite(const char *filename, const gsl_vector_long *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_long_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_long_fread(const char *filename, gsl_vector_long *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_long_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_long_fprintf(const char *filename, const gsl_vector_long *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_long_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_long_fscanf(const char *filename, gsl_vector_long *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_long_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_ulong_fwrite(const char *filename, const gsl_vector_ulong *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_ulong_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_ulong_fread(const char *filename, gsl_vector_ulong *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_ulong_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_ulong_fprintf(const char *filename, const gsl_vector_ulong *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_ulong_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_ulong_fscanf(const char *filename, gsl_vector_ulong *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_ulong_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_short_fwrite(const char *filename, const gsl_vector_short *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_short_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_short_fread(const char *filename, gsl_vector_short *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_short_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_short_fprintf(const char *filename, const gsl_vector_short *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_short_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_short_fscanf(const char *filename, gsl_vector_short *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_short_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_ushort_fwrite(const char *filename, const gsl_vector_ushort *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_ushort_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_ushort_fread(const char *filename, gsl_vector_ushort *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_ushort_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_ushort_fprintf(const char *filename, const gsl_vector_ushort *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_ushort_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_ushort_fscanf(const char *filename, gsl_vector_ushort *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_ushort_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_char_fwrite(const char *filename, const gsl_vector_char *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_char_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_char_fread(const char *filename, gsl_vector_char *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_char_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_char_fprintf(const char *filename, const gsl_vector_char *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_char_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_char_fscanf(const char *filename, gsl_vector_char *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_char_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_uchar_fwrite(const char *filename, const gsl_vector_uchar *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_uchar_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_uchar_fread(const char *filename, gsl_vector_uchar *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_uchar_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_uchar_fprintf(const char *filename, const gsl_vector_uchar *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_uchar_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_uchar_fscanf(const char *filename, gsl_vector_uchar *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_uchar_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_complex_fwrite(const char *filename, const gsl_vector_complex *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_complex_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_complex_fread(const char *filename, gsl_vector_complex *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_complex_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_complex_fprintf(const char *filename, const gsl_vector_complex *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_complex_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_complex_fscanf(const char *filename, gsl_vector_complex *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_complex_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_complex_float_fwrite(const char *filename, const gsl_vector_complex_float *v)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_complex_float_fwrite(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_complex_float_fread(const char *filename, gsl_vector_complex_float *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_complex_float_fread(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_complex_float_fprintf(const char *filename, const gsl_vector_complex_float *v, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_vector_complex_float_fprintf(fp, v, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_vector_complex_float_fscanf(const char *filename, gsl_vector_complex_float *v)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_vector_complex_float_fscanf(fp, v) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

/* Vector view */
gsl_vector_view *alloc_gsl_vector_view(void)
{
  gsl_vector_view *c = calloc(1, sizeof(gsl_vector_view));
  return c;
}

void free_gsl_vector_view(gsl_vector_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector *mgsl_vector_subvector(gsl_vector_view *view, gsl_vector *v, size_t offset, size_t n)
{
  *view = gsl_vector_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector *mgsl_vector_subvector_with_stride(gsl_vector_view *view, gsl_vector *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector *mgsl_vector_complex_real(gsl_vector_view *view, gsl_vector_complex *v)
{
  *view = gsl_vector_complex_real(v);
  return &view->vector;
}

gsl_vector *mgsl_vector_complex_imag(gsl_vector_view *view, gsl_vector_complex *v)
{
  *view = gsl_vector_complex_imag(v);
  return &view->vector;
}

gsl_vector_float *mgsl_vector_complex_float_real(gsl_vector_float_view *view, gsl_vector_complex_float *v)
{
  *view = gsl_vector_complex_float_real(v);
  return &view->vector;
}

gsl_vector_float *mgsl_vector_complex_float_imag(gsl_vector_float_view *view, gsl_vector_complex_float *v)
{
  *view = gsl_vector_complex_float_imag(v);
  return &view->vector;
}

gsl_vector *mgsl_vector_view_array(gsl_vector_view *view, double *base, size_t n)
{
  *view = gsl_vector_view_array(base, n);
  return &view->vector;
}

gsl_vector *mgsl_vector_view_array_with_stride(gsl_vector_view *view, double *base, size_t stride, size_t n)
{
  *view = gsl_vector_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_float_view *alloc_gsl_vector_float_view(void)
{
  gsl_vector_float_view *c = calloc(1, sizeof(gsl_vector_float_view));
  return c;
}

void free_gsl_vector_float_view(gsl_vector_float_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_float *mgsl_vector_float_subvector(gsl_vector_float_view *view, gsl_vector_float *v, size_t offset, size_t n)
{
  *view = gsl_vector_float_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_float *mgsl_vector_float_subvector_with_stride(gsl_vector_float_view *view, gsl_vector_float *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_float_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_float *mgsl_vector_float_view_array(gsl_vector_float_view *view, float *base, size_t n)
{
  *view = gsl_vector_float_view_array(base, n);
  return &view->vector;
}

gsl_vector_float *mgsl_vector_float_view_array_with_stride(gsl_vector_float_view *view, float *base, size_t stride, size_t n)
{
  *view = gsl_vector_float_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_int_view *alloc_gsl_vector_int_view(void)
{
  gsl_vector_int_view *c = calloc(1, sizeof(gsl_vector_int_view));
  return c;
}

void free_gsl_vector_int_view(gsl_vector_int_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_int *mgsl_vector_int_subvector(gsl_vector_int_view *view, gsl_vector_int *v, size_t offset, size_t n)
{
  *view = gsl_vector_int_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_int *mgsl_vector_int_subvector_with_stride(gsl_vector_int_view *view, gsl_vector_int *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_int_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_int *mgsl_vector_int_view_array(gsl_vector_int_view *view, int *base, size_t n)
{
  *view = gsl_vector_int_view_array(base, n);
  return &view->vector;
}

gsl_vector_int *mgsl_vector_int_view_array_with_stride(gsl_vector_int_view *view, int *base, size_t stride, size_t n)
{
  *view = gsl_vector_int_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_uint_view *alloc_gsl_vector_uint_view(void)
{
  gsl_vector_uint_view *c = calloc(1, sizeof(gsl_vector_uint_view));
  return c;
}

void free_gsl_vector_uint_view(gsl_vector_uint_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_uint *mgsl_vector_uint_subvector(gsl_vector_uint_view *view, gsl_vector_uint *v, size_t offset, size_t n)
{
  *view = gsl_vector_uint_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_uint *mgsl_vector_uint_subvector_with_stride(gsl_vector_uint_view *view, gsl_vector_uint *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_uint_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_uint *mgsl_vector_uint_view_array(gsl_vector_uint_view *view, unsigned int *base, size_t n)
{
  *view = gsl_vector_uint_view_array(base, n);
  return &view->vector;
}

gsl_vector_uint *mgsl_vector_uint_view_array_with_stride(gsl_vector_uint_view *view, unsigned int *base, size_t stride, size_t n)
{
  *view = gsl_vector_uint_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_long_view *alloc_gsl_vector_long_view(void)
{
  gsl_vector_long_view *c = calloc(1, sizeof(gsl_vector_long_view));
  return c;
}

void free_gsl_vector_long_view(gsl_vector_long_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_long *mgsl_vector_long_subvector(gsl_vector_long_view *view, gsl_vector_long *v, size_t offset, size_t n)
{
  *view = gsl_vector_long_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_long *mgsl_vector_long_subvector_with_stride(gsl_vector_long_view *view, gsl_vector_long *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_long_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_long *mgsl_vector_long_view_array(gsl_vector_long_view *view, long *base, size_t n)
{
  *view = gsl_vector_long_view_array(base, n);
  return &view->vector;
}

gsl_vector_long *mgsl_vector_long_view_array_with_stride(gsl_vector_long_view *view, long *base, size_t stride, size_t n)
{
  *view = gsl_vector_long_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_ulong_view *alloc_gsl_vector_ulong_view(void)
{
  gsl_vector_ulong_view *c = calloc(1, sizeof(gsl_vector_ulong_view));
  return c;
}

void free_gsl_vector_ulong_view(gsl_vector_ulong_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_ulong *mgsl_vector_ulong_subvector(gsl_vector_ulong_view *view, gsl_vector_ulong *v, size_t offset, size_t n)
{
  *view = gsl_vector_ulong_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_ulong *mgsl_vector_ulong_subvector_with_stride(gsl_vector_ulong_view *view, gsl_vector_ulong *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_ulong_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_ulong *mgsl_vector_ulong_view_array(gsl_vector_ulong_view *view, unsigned long *base, size_t n)
{
  *view = gsl_vector_ulong_view_array(base, n);
  return &view->vector;
}

gsl_vector_ulong *mgsl_vector_ulong_view_array_with_stride(gsl_vector_ulong_view *view, unsigned long *base, size_t stride, size_t n)
{
  *view = gsl_vector_ulong_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_short_view *alloc_gsl_vector_short_view(void)
{
  gsl_vector_short_view *c = calloc(1, sizeof(gsl_vector_short_view));
  return c;
}

void free_gsl_vector_short_view(gsl_vector_short_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_short *mgsl_vector_short_subvector(gsl_vector_short_view *view, gsl_vector_short *v, size_t offset, size_t n)
{
  *view = gsl_vector_short_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_short *mgsl_vector_short_subvector_with_stride(gsl_vector_short_view *view, gsl_vector_short *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_short_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_short *mgsl_vector_short_view_array(gsl_vector_short_view *view, short *base, size_t n)
{
  *view = gsl_vector_short_view_array(base, n);
  return &view->vector;
}

gsl_vector_short *mgsl_vector_short_view_array_with_stride(gsl_vector_short_view *view, short *base, size_t stride, size_t n)
{
  *view = gsl_vector_short_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_ushort_view *alloc_gsl_vector_ushort_view(void)
{
  gsl_vector_ushort_view *c = calloc(1, sizeof(gsl_vector_ushort_view));
  return c;
}

void free_gsl_vector_ushort_view(gsl_vector_ushort_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_ushort *mgsl_vector_ushort_subvector(gsl_vector_ushort_view *view, gsl_vector_ushort *v, size_t offset, size_t n)
{
  *view = gsl_vector_ushort_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_ushort *mgsl_vector_ushort_subvector_with_stride(gsl_vector_ushort_view *view, gsl_vector_ushort *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_ushort_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_ushort *mgsl_vector_ushort_view_array(gsl_vector_ushort_view *view, unsigned short *base, size_t n)
{
  *view = gsl_vector_ushort_view_array(base, n);
  return &view->vector;
}

gsl_vector_ushort *mgsl_vector_ushort_view_array_with_stride(gsl_vector_ushort_view *view, unsigned short *base, size_t stride, size_t n)
{
  *view = gsl_vector_ushort_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_char_view *alloc_gsl_vector_char_view(void)
{
  gsl_vector_char_view *c = calloc(1, sizeof(gsl_vector_char_view));
  return c;
}

void free_gsl_vector_char_view(gsl_vector_char_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_char *mgsl_vector_char_subvector(gsl_vector_char_view *view, gsl_vector_char *v, size_t offset, size_t n)
{
  *view = gsl_vector_char_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_char *mgsl_vector_char_subvector_with_stride(gsl_vector_char_view *view, gsl_vector_char *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_char_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_char *mgsl_vector_char_view_array(gsl_vector_char_view *view, char *base, size_t n)
{
  *view = gsl_vector_char_view_array(base, n);
  return &view->vector;
}

gsl_vector_char *mgsl_vector_char_view_array_with_stride(gsl_vector_char_view *view, char *base, size_t stride, size_t n)
{
  *view = gsl_vector_char_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_uchar_view *alloc_gsl_vector_uchar_view(void)
{
  gsl_vector_uchar_view *c = calloc(1, sizeof(gsl_vector_uchar_view));
  return c;
}

void free_gsl_vector_uchar_view(gsl_vector_uchar_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_uchar *mgsl_vector_uchar_subvector(gsl_vector_uchar_view *view, gsl_vector_uchar *v, size_t offset, size_t n)
{
  *view = gsl_vector_uchar_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_uchar *mgsl_vector_uchar_subvector_with_stride(gsl_vector_uchar_view *view, gsl_vector_uchar *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_uchar_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_uchar *mgsl_vector_uchar_view_array(gsl_vector_uchar_view *view, unsigned char *base, size_t n)
{
  *view = gsl_vector_uchar_view_array(base, n);
  return &view->vector;
}

gsl_vector_uchar *mgsl_vector_uchar_view_array_with_stride(gsl_vector_uchar_view *view, unsigned char *base, size_t stride, size_t n)
{
  *view = gsl_vector_uchar_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_complex_view *alloc_gsl_vector_complex_view(void)
{
  gsl_vector_complex_view *c = calloc(1, sizeof(gsl_vector_complex_view));
  return c;
}

void free_gsl_vector_complex_view(gsl_vector_complex_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_complex *mgsl_vector_complex_subvector(gsl_vector_complex_view *view, gsl_vector_complex *v, size_t offset, size_t n)
{
  *view = gsl_vector_complex_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_complex *mgsl_vector_complex_subvector_with_stride(gsl_vector_complex_view *view, gsl_vector_complex *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_complex_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_complex *mgsl_vector_complex_view_array(gsl_vector_complex_view *view, double *base, size_t n)
{
  *view = gsl_vector_complex_view_array(base, n);
  return &view->vector;
}

gsl_vector_complex *mgsl_vector_complex_view_array_with_stride(gsl_vector_complex_view *view, double *base, size_t stride, size_t n)
{
  *view = gsl_vector_complex_view_array_with_stride(base, stride, n);
  return &view->vector;
}

gsl_vector_complex_float_view *alloc_gsl_vector_complex_float_view(void)
{
  gsl_vector_complex_float_view *c = calloc(1, sizeof(gsl_vector_complex_float_view));
  return c;
}

void free_gsl_vector_complex_float_view(gsl_vector_complex_float_view *c)
{
  if(c != NULL){
    free(c);
    c = NULL;
  }
}

gsl_vector_complex_float *mgsl_vector_complex_float_subvector(gsl_vector_complex_float_view *view, gsl_vector_complex_float *v, size_t offset, size_t n)
{
  *view = gsl_vector_complex_float_subvector(v, offset, n);
  return &view->vector;
}

gsl_vector_complex_float *mgsl_vector_complex_float_subvector_with_stride(gsl_vector_complex_float_view *view, gsl_vector_complex_float *v, size_t offset, size_t stride, size_t n)
{
  *view = gsl_vector_complex_float_subvector_with_stride(v, offset, stride, n);
  return &view->vector;
}

gsl_vector_complex_float *mgsl_vector_complex_float_view_array(gsl_vector_complex_float_view *view, float *base, size_t n)
{
  *view = gsl_vector_complex_float_view_array(base, n);
  return &view->vector;
}

gsl_vector_complex_float *mgsl_vector_complex_float_view_array_with_stride(gsl_vector_complex_float_view *view, float *base, size_t stride, size_t n)
{
  *view = gsl_vector_complex_float_view_array_with_stride(base, stride, n);
  return &view->vector;
}

/* Complex vectors */
void mgsl_vector_complex_get(gsl_vector_complex *v, size_t i, gsl_complex *res)
{
  *res = gsl_vector_complex_get(v, i);
}

void mgsl_vector_complex_set(gsl_vector_complex *v, size_t i, gsl_complex *x)
{
  gsl_vector_complex_set(v, i, *x);
}

void mgsl_vector_complex_float_get(gsl_vector_complex_float *v, size_t i, gsl_complex_float *res)
{
  *res = gsl_vector_complex_float_get(v, i);
}

void mgsl_vector_complex_float_set(gsl_vector_complex_float *v, size_t i, gsl_complex_float *x)
{
  gsl_vector_complex_float_set(v, i, *x);
}

void mgsl_vector_complex_set_all(gsl_vector_complex *v, gsl_complex *x)
{
  gsl_vector_complex_set_all(v, *x);
}

void mgsl_vector_complex_float_set_all(gsl_vector_complex_float *v, gsl_complex_float *x)
{
  gsl_vector_complex_float_set_all(v, *x);
}

int mgsl_vector_complex_scale(gsl_vector_complex *a, gsl_complex *x)
{
  return gsl_vector_complex_scale(a, *x);
}

int mgsl_vector_complex_float_scale(gsl_vector_complex_float *a, gsl_complex_float *x)
{
  return gsl_vector_complex_float_scale(a, *x);
}

int mgsl_vector_complex_add_constant(gsl_vector_complex *a, gsl_complex *x)
{
  return gsl_vector_complex_add_constant(a, *x);
}

int mgsl_vector_complex_float_add_constant(gsl_vector_complex_float *a, gsl_complex_float *x)
{
  return gsl_vector_complex_float_add_constant(a, *x);
}

/* Matrix IO */
void mgsl_matrix_complex_get(gsl_matrix_complex *v, size_t i, size_t j, gsl_complex *res)
{
  *res = gsl_matrix_complex_get(v, i, j);
}

void mgsl_matrix_complex_set(gsl_matrix_complex *v, size_t i, size_t j, gsl_complex *x)
{
  gsl_matrix_complex_set(v, i, j, *x);
}

void mgsl_matrix_complex_float_get(gsl_matrix_complex_float *v, size_t i, size_t j, gsl_complex_float *res)
{
  *res = gsl_matrix_complex_float_get(v, i, j);
}

void mgsl_matrix_complex_float_set(gsl_matrix_complex_float *v, size_t i, size_t j, gsl_complex_float *x)
{
  gsl_matrix_complex_float_set(v, i, j, *x);
}

void mgsl_matrix_complex_set_all(gsl_matrix_complex *v, gsl_complex *x)
{
  gsl_matrix_complex_set_all(v, *x);
}

void mgsl_matrix_complex_float_set_all(gsl_matrix_complex_float *v, gsl_complex_float *x)
{
  gsl_matrix_complex_float_set_all(v, *x);
}

int mgsl_matrix_fwrite(const char *filename, const gsl_matrix *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_fread(const char *filename, gsl_matrix *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_fprintf(const char *filename, const gsl_matrix *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_fscanf(const char *filename, gsl_matrix *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_float_fwrite(const char *filename, const gsl_matrix_float *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_float_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_float_fread(const char *filename, gsl_matrix_float *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_float_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_float_fprintf(const char *filename, const gsl_matrix_float *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_float_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_float_fscanf(const char *filename, gsl_matrix_float *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_float_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_int_fwrite(const char *filename, const gsl_matrix_int *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_int_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_int_fread(const char *filename, gsl_matrix_int *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_int_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_int_fprintf(const char *filename, const gsl_matrix_int *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_int_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_int_fscanf(const char *filename, gsl_matrix_int *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_int_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_uint_fwrite(const char *filename, const gsl_matrix_uint *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_uint_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_uint_fread(const char *filename, gsl_matrix_uint *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_uint_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_uint_fprintf(const char *filename, const gsl_matrix_uint *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_uint_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_uint_fscanf(const char *filename, gsl_matrix_uint *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_uint_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_long_fwrite(const char *filename, const gsl_matrix_long *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_long_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_long_fread(const char *filename, gsl_matrix_long *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_long_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_long_fprintf(const char *filename, const gsl_matrix_long *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_long_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_long_fscanf(const char *filename, gsl_matrix_long *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_long_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_ulong_fwrite(const char *filename, const gsl_matrix_ulong *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_ulong_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_ulong_fread(const char *filename, gsl_matrix_ulong *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_ulong_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_ulong_fprintf(const char *filename, const gsl_matrix_ulong *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_ulong_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_ulong_fscanf(const char *filename, gsl_matrix_ulong *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_ulong_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_short_fwrite(const char *filename, const gsl_matrix_short *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_short_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_short_fread(const char *filename, gsl_matrix_short *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_short_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_short_fprintf(const char *filename, const gsl_matrix_short *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_short_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_short_fscanf(const char *filename, gsl_matrix_short *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_short_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_ushort_fwrite(const char *filename, const gsl_matrix_ushort *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_ushort_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_ushort_fread(const char *filename, gsl_matrix_ushort *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_ushort_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_ushort_fprintf(const char *filename, const gsl_matrix_ushort *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_ushort_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_ushort_fscanf(const char *filename, gsl_matrix_ushort *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_ushort_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_char_fwrite(const char *filename, const gsl_matrix_char *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_char_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_char_fread(const char *filename, gsl_matrix_char *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_char_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_char_fprintf(const char *filename, const gsl_matrix_char *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_char_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_char_fscanf(const char *filename, gsl_matrix_char *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_char_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_uchar_fwrite(const char *filename, const gsl_matrix_uchar *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_uchar_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_uchar_fread(const char *filename, gsl_matrix_uchar *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_uchar_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_uchar_fprintf(const char *filename, const gsl_matrix_uchar *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_uchar_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_uchar_fscanf(const char *filename, gsl_matrix_uchar *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_uchar_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_complex_fwrite(const char *filename, const gsl_matrix_complex *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_complex_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_complex_fread(const char *filename, gsl_matrix_complex *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_complex_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_complex_fprintf(const char *filename, const gsl_matrix_complex *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_complex_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_complex_fscanf(const char *filename, gsl_matrix_complex *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_complex_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_complex_float_fwrite(const char *filename, const gsl_matrix_complex_float *m)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_complex_float_fwrite(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_complex_float_fread(const char *filename, gsl_matrix_complex_float *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_complex_float_fread(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_complex_float_fprintf(const char *filename, const gsl_matrix_complex_float *m, const char *format)
{
  FILE *fp;
  if((fp = fopen(filename, "w")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_complex_float_fprintf(fp, m, format) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

int mgsl_matrix_complex_float_fscanf(const char *filename, gsl_matrix_complex_float *m)
{
  FILE *fp;
  if((fp = fopen(filename, "r")) == NULL) return GSL_EFAILED;
  if(gsl_matrix_complex_float_fscanf(fp, m) != GSL_SUCCESS) return GSL_EFAILED;
  fclose(fp);
  return GSL_SUCCESS;
}

/* Matrix view */
gsl_matrix_view *alloc_gsl_matrix_view(void)
{
  gsl_matrix_view *m = calloc(1, sizeof(gsl_matrix_view));
  return m;
}

void free_gsl_matrix_view(gsl_matrix_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix *mgsl_matrix_submatrix(gsl_matrix_view *view, gsl_matrix *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix *mgsl_matrix_view_array(gsl_matrix_view *view, double *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix *mgsl_matrix_view_array_with_tda(gsl_matrix_view *view, double *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix *mgsl_matrix_view_vector(gsl_matrix_view *view, gsl_vector *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix *mgsl_matrix_view_vector_with_tda(gsl_matrix_view *view, gsl_vector *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_float_view *alloc_gsl_matrix_float_view(void)
{
  gsl_matrix_float_view *m = calloc(1, sizeof(gsl_matrix_float_view));
  return m;
}

void free_gsl_matrix_float_view(gsl_matrix_float_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_float *mgsl_matrix_float_submatrix(gsl_matrix_float_view *view, gsl_matrix_float *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_float_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_float *mgsl_matrix_float_view_array(gsl_matrix_float_view *view, float *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_float_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_float *mgsl_matrix_float_view_array_with_tda(gsl_matrix_float_view *view, float *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_float_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_float *mgsl_matrix_float_view_vector(gsl_matrix_float_view *view, gsl_vector_float *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_float_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_float *mgsl_matrix_float_view_vector_with_tda(gsl_matrix_float_view *view, gsl_vector_float *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_float_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_int_view *alloc_gsl_matrix_int_view(void)
{
  gsl_matrix_int_view *m = calloc(1, sizeof(gsl_matrix_int_view));
  return m;
}

void free_gsl_matrix_int_view(gsl_matrix_int_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_int *mgsl_matrix_int_submatrix(gsl_matrix_int_view *view, gsl_matrix_int *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_int_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_int *mgsl_matrix_int_view_array(gsl_matrix_int_view *view, int *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_int_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_int *mgsl_matrix_int_view_array_with_tda(gsl_matrix_int_view *view, int *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_int_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_int *mgsl_matrix_int_view_vector(gsl_matrix_int_view *view, gsl_vector_int *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_int_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_int *mgsl_matrix_int_view_vector_with_tda(gsl_matrix_int_view *view, gsl_vector_int *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_int_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_uint_view *alloc_gsl_matrix_uint_view(void)
{
  gsl_matrix_uint_view *m = calloc(1, sizeof(gsl_matrix_uint_view));
  return m;
}

void free_gsl_matrix_uint_view(gsl_matrix_uint_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_uint *mgsl_matrix_uint_submatrix(gsl_matrix_uint_view *view, gsl_matrix_uint *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_uint_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_uint *mgsl_matrix_uint_view_array(gsl_matrix_uint_view *view, unsigned int *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_uint_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_uint *mgsl_matrix_uint_view_array_with_tda(gsl_matrix_uint_view *view, unsigned int *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_uint_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_uint *mgsl_matrix_uint_view_vector(gsl_matrix_uint_view *view, gsl_vector_uint *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_uint_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_uint *mgsl_matrix_uint_view_vector_with_tda(gsl_matrix_uint_view *view, gsl_vector_uint *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_uint_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_long_view *alloc_gsl_matrix_long_view(void)
{
  gsl_matrix_long_view *m = calloc(1, sizeof(gsl_matrix_long_view));
  return m;
}

void free_gsl_matrix_long_view(gsl_matrix_long_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_long *mgsl_matrix_long_submatrix(gsl_matrix_long_view *view, gsl_matrix_long *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_long_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_long *mgsl_matrix_long_view_array(gsl_matrix_long_view *view, long *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_long_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_long *mgsl_matrix_long_view_array_with_tda(gsl_matrix_long_view *view, long *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_long_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_long *mgsl_matrix_long_view_vector(gsl_matrix_long_view *view, gsl_vector_long *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_long_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_long *mgsl_matrix_long_view_vector_with_tda(gsl_matrix_long_view *view, gsl_vector_long *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_long_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_ulong_view *alloc_gsl_matrix_ulong_view(void)
{
  gsl_matrix_ulong_view *m = calloc(1, sizeof(gsl_matrix_ulong_view));
  return m;
}

void free_gsl_matrix_ulong_view(gsl_matrix_ulong_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_ulong *mgsl_matrix_ulong_submatrix(gsl_matrix_ulong_view *view, gsl_matrix_ulong *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_ulong_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_ulong *mgsl_matrix_ulong_view_array(gsl_matrix_ulong_view *view, unsigned long *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_ulong_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_ulong *mgsl_matrix_ulong_view_array_with_tda(gsl_matrix_ulong_view *view, unsigned long *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_ulong_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_ulong *mgsl_matrix_ulong_view_vector(gsl_matrix_ulong_view *view, gsl_vector_ulong *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_ulong_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_ulong *mgsl_matrix_ulong_view_vector_with_tda(gsl_matrix_ulong_view *view, gsl_vector_ulong *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_ulong_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_short_view *alloc_gsl_matrix_short_view(void)
{
  gsl_matrix_short_view *m = calloc(1, sizeof(gsl_matrix_short_view));
  return m;
}

void free_gsl_matrix_short_view(gsl_matrix_short_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_short *mgsl_matrix_short_submatrix(gsl_matrix_short_view *view, gsl_matrix_short *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_short_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_short *mgsl_matrix_short_view_array(gsl_matrix_short_view *view, short *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_short_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_short *mgsl_matrix_short_view_array_with_tda(gsl_matrix_short_view *view, short *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_short_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_short *mgsl_matrix_short_view_vector(gsl_matrix_short_view *view, gsl_vector_short *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_short_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_short *mgsl_matrix_short_view_vector_with_tda(gsl_matrix_short_view *view, gsl_vector_short *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_short_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_ushort_view *alloc_gsl_matrix_ushort_view(void)
{
  gsl_matrix_ushort_view *m = calloc(1, sizeof(gsl_matrix_ushort_view));
  return m;
}

void free_gsl_matrix_ushort_view(gsl_matrix_ushort_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_ushort *mgsl_matrix_ushort_submatrix(gsl_matrix_ushort_view *view, gsl_matrix_ushort *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_ushort_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_ushort *mgsl_matrix_ushort_view_array(gsl_matrix_ushort_view *view, unsigned short *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_ushort_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_ushort *mgsl_matrix_ushort_view_array_with_tda(gsl_matrix_ushort_view *view, unsigned short *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_ushort_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_ushort *mgsl_matrix_ushort_view_vector(gsl_matrix_ushort_view *view, gsl_vector_ushort *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_ushort_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_ushort *mgsl_matrix_ushort_view_vector_with_tda(gsl_matrix_ushort_view *view, gsl_vector_ushort *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_ushort_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_char_view *alloc_gsl_matrix_char_view(void)
{
  gsl_matrix_char_view *m = calloc(1, sizeof(gsl_matrix_char_view));
  return m;
}

void free_gsl_matrix_char_view(gsl_matrix_char_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_char *mgsl_matrix_char_submatrix(gsl_matrix_char_view *view, gsl_matrix_char *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_char_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_char *mgsl_matrix_char_view_array(gsl_matrix_char_view *view, char *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_char_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_char *mgsl_matrix_char_view_array_with_tda(gsl_matrix_char_view *view, char *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_char_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_char *mgsl_matrix_char_view_vector(gsl_matrix_char_view *view, gsl_vector_char *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_char_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_char *mgsl_matrix_char_view_vector_with_tda(gsl_matrix_char_view *view, gsl_vector_char *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_char_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_uchar_view *alloc_gsl_matrix_uchar_view(void)
{
  gsl_matrix_uchar_view *m = calloc(1, sizeof(gsl_matrix_uchar_view));
  return m;
}

void free_gsl_matrix_uchar_view(gsl_matrix_uchar_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_uchar *mgsl_matrix_uchar_submatrix(gsl_matrix_uchar_view *view, gsl_matrix_uchar *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_uchar_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_uchar *mgsl_matrix_uchar_view_array(gsl_matrix_uchar_view *view, unsigned char *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_uchar_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_uchar *mgsl_matrix_uchar_view_array_with_tda(gsl_matrix_uchar_view *view, unsigned char *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_uchar_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_uchar *mgsl_matrix_uchar_view_vector(gsl_matrix_uchar_view *view, gsl_vector_uchar *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_uchar_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_uchar *mgsl_matrix_uchar_view_vector_with_tda(gsl_matrix_uchar_view *view, gsl_vector_uchar *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_uchar_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_complex_view *alloc_gsl_matrix_complex_view(void)
{
  gsl_matrix_complex_view *m = calloc(1, sizeof(gsl_matrix_complex_view));
  return m;
}

void free_gsl_matrix_complex_view(gsl_matrix_complex_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_complex *mgsl_matrix_complex_submatrix(gsl_matrix_complex_view *view, gsl_matrix_complex *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_complex_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_complex *mgsl_matrix_complex_view_array(gsl_matrix_complex_view *view, double *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_complex_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_complex *mgsl_matrix_complex_view_array_with_tda(gsl_matrix_complex_view *view, double *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_complex_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_complex *mgsl_matrix_complex_view_vector(gsl_matrix_complex_view *view, gsl_vector_complex *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_complex_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_complex *mgsl_matrix_complex_view_vector_with_tda(gsl_matrix_complex_view *view, gsl_vector_complex *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_complex_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_complex_float_view *alloc_gsl_matrix_complex_float_view(void)
{
  gsl_matrix_complex_float_view *m = calloc(1, sizeof(gsl_matrix_complex_float_view));
  return m;
}

void free_gsl_matrix_complex_float_view(gsl_matrix_complex_float_view *m)
{
  if(m != NULL){
    free(m);
    m = NULL;
  }
}

gsl_matrix_complex_float *mgsl_matrix_complex_float_submatrix(gsl_matrix_complex_float_view *view, gsl_matrix_complex_float *m, size_t k1, size_t k2, size_t n1, size_t n2)
{
  *view = gsl_matrix_complex_float_submatrix(m, k1, k2, n1, n2);
  return &view->matrix;
}

gsl_matrix_complex_float *mgsl_matrix_complex_float_view_array(gsl_matrix_complex_float_view *view, float *base, size_t n1, size_t n2)
{
  *view = gsl_matrix_complex_float_view_array(base, n1, n2);
  return &view->matrix;
}

gsl_matrix_complex_float *mgsl_matrix_complex_float_view_array_with_tda(gsl_matrix_complex_float_view *view, float *base, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_complex_float_view_array_with_tda(base, n1, n2, tda);
  return &view->matrix;
}

gsl_matrix_complex_float *mgsl_matrix_complex_float_view_vector(gsl_matrix_complex_float_view *view, gsl_vector_complex_float *v, size_t n1, size_t n2)
{
  *view = gsl_matrix_complex_float_view_vector(v, n1, n2);
  return &view->matrix;
}

gsl_matrix_complex_float *mgsl_matrix_complex_float_view_vector_with_tda(gsl_matrix_complex_float_view *view, gsl_vector_complex_float *v, size_t n1, size_t n2, size_t tda)
{
  *view = gsl_matrix_complex_float_view_vector_with_tda(v, n1, n2, tda);
  return &view->matrix;
}

/* Matrix row and column view */
gsl_vector *mgsl_matrix_row(gsl_vector_view *view, gsl_matrix *m, size_t i)
{
  *view = gsl_matrix_row(m, i);
  return &view->vector;
}

gsl_vector_float *mgsl_matrix_float_row(gsl_vector_float_view *view, gsl_matrix_float *m, size_t i)
{
  *view = gsl_matrix_float_row(m, i);
  return &view->vector;
}

gsl_vector_int *mgsl_matrix_int_row(gsl_vector_int_view *view, gsl_matrix_int *m, size_t i)
{
  *view = gsl_matrix_int_row(m, i);
  return &view->vector;
}

gsl_vector_uint *mgsl_matrix_uint_row(gsl_vector_uint_view *view, gsl_matrix_uint *m, size_t i)
{
  *view = gsl_matrix_uint_row(m, i);
  return &view->vector;
}

gsl_vector_long *mgsl_matrix_long_row(gsl_vector_long_view *view, gsl_matrix_long *m, size_t i)
{
  *view = gsl_matrix_long_row(m, i);
  return &view->vector;
}

gsl_vector_ulong *mgsl_matrix_ulong_row(gsl_vector_ulong_view *view, gsl_matrix_ulong *m, size_t i)
{
  *view = gsl_matrix_ulong_row(m, i);
  return &view->vector;
}

gsl_vector_short *mgsl_matrix_short_row(gsl_vector_short_view *view, gsl_matrix_short *m, size_t i)
{
  *view = gsl_matrix_short_row(m, i);
  return &view->vector;
}

gsl_vector_ushort *mgsl_matrix_ushort_row(gsl_vector_ushort_view *view, gsl_matrix_ushort *m, size_t i)
{
  *view = gsl_matrix_ushort_row(m, i);
  return &view->vector;
}

gsl_vector_char *mgsl_matrix_char_row(gsl_vector_char_view *view, gsl_matrix_char *m, size_t i)
{
  *view = gsl_matrix_char_row(m, i);
  return &view->vector;
}

gsl_vector_uchar *mgsl_matrix_uchar_row(gsl_vector_uchar_view *view, gsl_matrix_uchar *m, size_t i)
{
  *view = gsl_matrix_uchar_row(m, i);
  return &view->vector;
}

gsl_vector_complex *mgsl_matrix_complex_row(gsl_vector_complex_view *view, gsl_matrix_complex *m, size_t i)
{
  *view = gsl_matrix_complex_row(m, i);
  return &view->vector;
}

gsl_vector_complex_float *mgsl_matrix_complex_float_row(gsl_vector_complex_float_view *view, gsl_matrix_complex_float *m, size_t i)
{
  *view = gsl_matrix_complex_float_row(m, i);
  return &view->vector;
}

gsl_vector *mgsl_matrix_column(gsl_vector_view *view, gsl_matrix *m, size_t j)
{
  *view = gsl_matrix_column(m, j);
  return &view->vector;
}

gsl_vector_float *mgsl_matrix_float_column(gsl_vector_float_view *view, gsl_matrix_float *m, size_t j)
{
  *view = gsl_matrix_float_column(m, j);
  return &view->vector;
}

gsl_vector_int *mgsl_matrix_int_column(gsl_vector_int_view *view, gsl_matrix_int *m, size_t j)
{
  *view = gsl_matrix_int_column(m, j);
  return &view->vector;
}

gsl_vector_uint *mgsl_matrix_uint_column(gsl_vector_uint_view *view, gsl_matrix_uint *m, size_t j)
{
  *view = gsl_matrix_uint_column(m, j);
  return &view->vector;
}

gsl_vector_long *mgsl_matrix_long_column(gsl_vector_long_view *view, gsl_matrix_long *m, size_t j)
{
  *view = gsl_matrix_long_column(m, j);
  return &view->vector;
}

gsl_vector_ulong *mgsl_matrix_ulong_column(gsl_vector_ulong_view *view, gsl_matrix_ulong *m, size_t j)
{
  *view = gsl_matrix_ulong_column(m, j);
  return &view->vector;
}

gsl_vector_short *mgsl_matrix_short_column(gsl_vector_short_view *view, gsl_matrix_short *m, size_t j)
{
  *view = gsl_matrix_short_column(m, j);
  return &view->vector;
}

gsl_vector_ushort *mgsl_matrix_ushort_column(gsl_vector_ushort_view *view, gsl_matrix_ushort *m, size_t j)
{
  *view = gsl_matrix_ushort_column(m, j);
  return &view->vector;
}

gsl_vector_char *mgsl_matrix_char_column(gsl_vector_char_view *view, gsl_matrix_char *m, size_t j)
{
  *view = gsl_matrix_char_column(m, j);
  return &view->vector;
}

gsl_vector_uchar *mgsl_matrix_uchar_column(gsl_vector_uchar_view *view, gsl_matrix_uchar *m, size_t j)
{
  *view = gsl_matrix_uchar_column(m, j);
  return &view->vector;
}

gsl_vector_complex *mgsl_matrix_complex_column(gsl_vector_complex_view *view, gsl_matrix_complex *m, size_t j)
{
  *view = gsl_matrix_complex_column(m, j);
  return &view->vector;
}

gsl_vector_complex_float *mgsl_matrix_complex_float_column(gsl_vector_complex_float_view *view, gsl_matrix_complex_float *m, size_t j)
{
  *view = gsl_matrix_complex_float_column(m, j);
  return &view->vector;
}

gsl_vector *mgsl_matrix_subrow(gsl_vector_view *view, gsl_matrix *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_float *mgsl_matrix_float_subrow(gsl_vector_float_view *view, gsl_matrix_float *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_float_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_int *mgsl_matrix_int_subrow(gsl_vector_int_view *view, gsl_matrix_int *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_int_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_uint *mgsl_matrix_uint_subrow(gsl_vector_uint_view *view, gsl_matrix_uint *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_uint_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_long *mgsl_matrix_long_subrow(gsl_vector_long_view *view, gsl_matrix_long *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_long_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_ulong *mgsl_matrix_ulong_subrow(gsl_vector_ulong_view *view, gsl_matrix_ulong *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_ulong_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_short *mgsl_matrix_short_subrow(gsl_vector_short_view *view, gsl_matrix_short *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_short_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_ushort *mgsl_matrix_ushort_subrow(gsl_vector_ushort_view *view, gsl_matrix_ushort *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_ushort_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_char *mgsl_matrix_char_subrow(gsl_vector_char_view *view, gsl_matrix_char *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_char_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_uchar *mgsl_matrix_uchar_subrow(gsl_vector_uchar_view *view, gsl_matrix_uchar *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_uchar_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_complex *mgsl_matrix_complex_subrow(gsl_vector_complex_view *view, gsl_matrix_complex *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_complex_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector_complex_float *mgsl_matrix_complex_float_subrow(gsl_vector_complex_float_view *view, gsl_matrix_complex_float *m, size_t i, size_t offset, size_t n)
{
  *view = gsl_matrix_complex_float_subrow(m, i, offset, n);
  return &view->vector;
}

gsl_vector *mgsl_matrix_subcolumn(gsl_vector_view *view, gsl_matrix *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_float *mgsl_matrix_float_subcolumn(gsl_vector_float_view *view, gsl_matrix_float *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_float_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_int *mgsl_matrix_int_subcolumn(gsl_vector_int_view *view, gsl_matrix_int *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_int_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_uint *mgsl_matrix_uint_subcolumn(gsl_vector_uint_view *view, gsl_matrix_uint *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_uint_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_long *mgsl_matrix_long_subcolumn(gsl_vector_long_view *view, gsl_matrix_long *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_long_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_ulong *mgsl_matrix_ulong_subcolumn(gsl_vector_ulong_view *view, gsl_matrix_ulong *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_ulong_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_short *mgsl_matrix_short_subcolumn(gsl_vector_short_view *view, gsl_matrix_short *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_short_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_ushort *mgsl_matrix_ushort_subcolumn(gsl_vector_ushort_view *view, gsl_matrix_ushort *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_ushort_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_char *mgsl_matrix_char_subcolumn(gsl_vector_char_view *view, gsl_matrix_char *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_char_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_uchar *mgsl_matrix_uchar_subcolumn(gsl_vector_uchar_view *view, gsl_matrix_uchar *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_uchar_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_complex *mgsl_matrix_complex_subcolumn(gsl_vector_complex_view *view, gsl_matrix_complex *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_complex_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector_complex_float *mgsl_matrix_complex_float_subcolumn(gsl_vector_complex_float_view *view, gsl_matrix_complex_float *m, size_t j, size_t offset, size_t n)
{
  *view = gsl_matrix_complex_float_subcolumn(m, j, offset, n);
  return &view->vector;
}

gsl_vector *mgsl_matrix_diagonal(gsl_vector_view *view, gsl_matrix *m)
{
  *view = gsl_matrix_diagonal(m);
  return &view->vector;
}

gsl_vector_float *mgsl_matrix_float_diagonal(gsl_vector_float_view *view, gsl_matrix_float *m)
{
  *view = gsl_matrix_float_diagonal(m);
  return &view->vector;
}

gsl_vector_int *mgsl_matrix_int_diagonal(gsl_vector_int_view *view, gsl_matrix_int *m)
{
  *view = gsl_matrix_int_diagonal(m);
  return &view->vector;
}

gsl_vector_uint *mgsl_matrix_uint_diagonal(gsl_vector_uint_view *view, gsl_matrix_uint *m)
{
  *view = gsl_matrix_uint_diagonal(m);
  return &view->vector;
}

gsl_vector_long *mgsl_matrix_long_diagonal(gsl_vector_long_view *view, gsl_matrix_long *m)
{
  *view = gsl_matrix_long_diagonal(m);
  return &view->vector;
}

gsl_vector_ulong *mgsl_matrix_ulong_diagonal(gsl_vector_ulong_view *view, gsl_matrix_ulong *m)
{
  *view = gsl_matrix_ulong_diagonal(m);
  return &view->vector;
}

gsl_vector_short *mgsl_matrix_short_diagonal(gsl_vector_short_view *view, gsl_matrix_short *m)
{
  *view = gsl_matrix_short_diagonal(m);
  return &view->vector;
}

gsl_vector_ushort *mgsl_matrix_ushort_diagonal(gsl_vector_ushort_view *view, gsl_matrix_ushort *m)
{
  *view = gsl_matrix_ushort_diagonal(m);
  return &view->vector;
}

gsl_vector_char *mgsl_matrix_char_diagonal(gsl_vector_char_view *view, gsl_matrix_char *m)
{
  *view = gsl_matrix_char_diagonal(m);
  return &view->vector;
}

gsl_vector_uchar *mgsl_matrix_uchar_diagonal(gsl_vector_uchar_view *view, gsl_matrix_uchar *m)
{
  *view = gsl_matrix_uchar_diagonal(m);
  return &view->vector;
}

gsl_vector_complex *mgsl_matrix_complex_diagonal(gsl_vector_complex_view *view, gsl_matrix_complex *m)
{
  *view = gsl_matrix_complex_diagonal(m);
  return &view->vector;
}

gsl_vector_complex_float *mgsl_matrix_complex_float_diagonal(gsl_vector_complex_float_view *view, gsl_matrix_complex_float *m)
{
  *view = gsl_matrix_complex_float_diagonal(m);
  return &view->vector;
}

gsl_vector *mgsl_matrix_subdiagonal(gsl_vector_view *view, gsl_matrix *m, size_t k)
{
  *view = gsl_matrix_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_float *mgsl_matrix_float_subdiagonal(gsl_vector_float_view *view, gsl_matrix_float *m, size_t k)
{
  *view = gsl_matrix_float_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_int *mgsl_matrix_int_subdiagonal(gsl_vector_int_view *view, gsl_matrix_int *m, size_t k)
{
  *view = gsl_matrix_int_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_uint *mgsl_matrix_uint_subdiagonal(gsl_vector_uint_view *view, gsl_matrix_uint *m, size_t k)
{
  *view = gsl_matrix_uint_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_long *mgsl_matrix_long_subdiagonal(gsl_vector_long_view *view, gsl_matrix_long *m, size_t k)
{
  *view = gsl_matrix_long_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_ulong *mgsl_matrix_ulong_subdiagonal(gsl_vector_ulong_view *view, gsl_matrix_ulong *m, size_t k)
{
  *view = gsl_matrix_ulong_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_short *mgsl_matrix_short_subdiagonal(gsl_vector_short_view *view, gsl_matrix_short *m, size_t k)
{
  *view = gsl_matrix_short_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_ushort *mgsl_matrix_ushort_subdiagonal(gsl_vector_ushort_view *view, gsl_matrix_ushort *m, size_t k)
{
  *view = gsl_matrix_ushort_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_char *mgsl_matrix_char_subdiagonal(gsl_vector_char_view *view, gsl_matrix_char *m, size_t k)
{
  *view = gsl_matrix_char_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_uchar *mgsl_matrix_uchar_subdiagonal(gsl_vector_uchar_view *view, gsl_matrix_uchar *m, size_t k)
{
  *view = gsl_matrix_uchar_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_complex *mgsl_matrix_complex_subdiagonal(gsl_vector_complex_view *view, gsl_matrix_complex *m, size_t k)
{
  *view = gsl_matrix_complex_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector_complex_float *mgsl_matrix_complex_float_subdiagonal(gsl_vector_complex_float_view *view, gsl_matrix_complex_float *m, size_t k)
{
  *view = gsl_matrix_complex_float_subdiagonal(m, k);
  return &view->vector;
}

gsl_vector *mgsl_matrix_superdiagonal(gsl_vector_view *view, gsl_matrix *m, size_t k)
{
  *view = gsl_matrix_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_float *mgsl_matrix_float_superdiagonal(gsl_vector_float_view *view, gsl_matrix_float *m, size_t k)
{
  *view = gsl_matrix_float_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_int *mgsl_matrix_int_superdiagonal(gsl_vector_int_view *view, gsl_matrix_int *m, size_t k)
{
  *view = gsl_matrix_int_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_uint *mgsl_matrix_uint_superdiagonal(gsl_vector_uint_view *view, gsl_matrix_uint *m, size_t k)
{
  *view = gsl_matrix_uint_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_long *mgsl_matrix_long_superdiagonal(gsl_vector_long_view *view, gsl_matrix_long *m, size_t k)
{
  *view = gsl_matrix_long_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_ulong *mgsl_matrix_ulong_superdiagonal(gsl_vector_ulong_view *view, gsl_matrix_ulong *m, size_t k)
{
  *view = gsl_matrix_ulong_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_short *mgsl_matrix_short_superdiagonal(gsl_vector_short_view *view, gsl_matrix_short *m, size_t k)
{
  *view = gsl_matrix_short_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_ushort *mgsl_matrix_ushort_superdiagonal(gsl_vector_ushort_view *view, gsl_matrix_ushort *m, size_t k)
{
  *view = gsl_matrix_ushort_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_char *mgsl_matrix_char_superdiagonal(gsl_vector_char_view *view, gsl_matrix_char *m, size_t k)
{
  *view = gsl_matrix_char_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_uchar *mgsl_matrix_uchar_superdiagonal(gsl_vector_uchar_view *view, gsl_matrix_uchar *m, size_t k)
{
  *view = gsl_matrix_uchar_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_complex *mgsl_matrix_complex_superdiagonal(gsl_vector_complex_view *view, gsl_matrix_complex *m, size_t k)
{
  *view = gsl_matrix_complex_superdiagonal(m, k);
  return &view->vector;
}

gsl_vector_complex_float *mgsl_matrix_complex_float_superdiagonal(gsl_vector_complex_float_view *view, gsl_matrix_complex_float *m, size_t k)
{
  *view = gsl_matrix_complex_float_superdiagonal(m, k);
  return &view->vector;
}


/*****************************************************************\
           __
          / /
		 / /                     __  __
		/ /______    _______    / / / / ________   __       __
	   / ______  \  /_____  \  / / / / / _____  | / /      / /
	  / /      | / _______| / / / / / / /____/ / / /      / /
	 / /      / / / _____  / / / / / / _______/ / /      / /
	/ /      / / / /____/ / / / / / / |______  / |______/ /
   /_/      /_/ |________/ / / / /  \_______/  \_______  /
                          /_/ /_/                     / /
			                                         / /
		                                            /_/

  ---------------------------------------------------------------

  Copyright (c) 2007-2011 - Rodrigo Braz Monteiro.
  This file is subject to the terms of halley_license.txt.

\*****************************************************************/

#pragma once

#include <gsl/gsl>
#include "halley/maths/vector2.h"
#include "halley/text/halleystring.h"
#include "halley/resources/resource.h"
#include "halley/file/path.h"
#include "halley/maths/rect.h"
#include "halley/maths/colour.h"

namespace Halley {
	class ResourceDataStatic;
	class ResourceLoader;

	class Image final : public Resource {
	public:
		enum class Format {
			Undefined,
			Indexed,
			RGB,
			RGBA,
			RGBAPremultiplied,
			SingleChannel
		};

		Image(Format format = Format::RGBA, Vector2i size = {});
		Image(gsl::span<const gsl::byte> bytes, Format format = Format::Undefined);
		explicit Image(const ResourceDataStatic& data);
		Image(const ResourceDataStatic& data, const Metadata& meta);
		Image(Image&& other);
		~Image();

		std::unique_ptr<Image> clone();

		void setSize(Vector2i size);

		void load(gsl::span<const gsl::byte> bytes, Format format = Format::Undefined);
		Bytes savePNGToBytes(bool allowDepthReduce = true) const;
		Bytes saveQOIToBytes() const;
		static Vector2i getImageSize(gsl::span<const gsl::byte> bytes);
		static Format getImageFormat(gsl::span<const gsl::byte> bytes);

		static bool isQOI(gsl::span<const gsl::byte> bytes);
		static bool isPNG(gsl::span<const gsl::byte> bytes);

		gsl::span<unsigned char> getPixelBytes();
		gsl::span<const unsigned char> getPixelBytes() const;
		gsl::span<const unsigned char> getPixelBytesRow(int x0, int x1, int y) const;

		int getPixel4BPP(Vector2i pos) const;
		int getPixelAlpha(Vector2i pos) const;
		gsl::span<int> getPixels4BPP();
		gsl::span<const int> getPixels4BPP() const;
		gsl::span<const int> getPixelRow4BPP(int x0, int x1, int y) const;
		size_t getByteSize() const;

		static unsigned int convertRGBAToInt(unsigned int r, unsigned int g, unsigned int b, unsigned int a=255);
		static void convertIntToRGBA(unsigned int col, unsigned int& r, unsigned int& g, unsigned int& b, unsigned int& a);
		static Colour4c convertIntToColour(unsigned int col);

		unsigned int getWidth() const { return w; }
		unsigned int getHeight() const { return h; }
		Vector2i getSize() const { return Vector2i(int(w), int(h)); }

		int getBytesPerPixel() const;
		Format getFormat() const;

		Rect4i getTrimRect() const;
		Rect4i getRect() const;

		void clear(int colour);
		void blitFrom(Vector2i pos, gsl::span<const unsigned char> buffer, size_t width, size_t height, size_t pitch, size_t srcBpp);
		void blitFromRotated(Vector2i pos, gsl::span<const unsigned char> buffer, size_t width, size_t height, size_t pitch, size_t bpp);
		void blitFrom(Vector2i pos, const Image& srcImg, bool rotated = false);
		void blitFrom(Vector2i pos, const Image& srcImg, Rect4i srcArea, bool rotated = false);
		void blitDownsampled(Image& src, int scale);

		void drawImageAlpha(const Image& src, Vector2i pos, uint8_t opacity = 255);
		void drawImageAdd(const Image& src, Vector2i pos, uint8_t opacity = 255);
		void drawImageLighten(const Image& src, Vector2i pos, uint8_t opacity = 255);

		static std::unique_ptr<Image> loadResource(ResourceLoader& loader);
		constexpr static AssetType getAssetType() { return AssetType::Image; }
		void reload(Resource&& resource) override;

		Image& operator=(const Image& o) = delete;
		Image& operator=(Image&& o) = default;

		void serialize(Serializer& s) const;
		void deserialize(Deserializer& s);

		void preMultiply();

		ResourceMemoryUsage getMemoryUsage() const override;

	private:
		std::unique_ptr<unsigned char, void(*)(unsigned char*)> px;
		size_t dataLen = 0;
		unsigned int w = 0;
		unsigned int h = 0;
		Format format = Format::Undefined;
	};

	template <>
	struct EnumNames<Image::Format> {
		constexpr std::array<const char*, 6> operator()() const {
			return{{
				"undefined",
				"indexed",
				"rgb",
				"rgba",
				"rgba_premultiplied",
				"single_channel"
			}};
		}
	};
}


// This file is part of playd.
// playd is licensed under the MIT licence: see LICENSE.txt.

/**
 * @file
 * The Ring_buffer class.
 */

#ifndef PLAYD_RING_BUFFER_HPP
#define PLAYD_RING_BUFFER_HPP

#include <atomic>
#include <mutex>
#include <vector>

#undef max
#include <gsl/gsl>

namespace Playd::Audio
{
/**
 * A concurrent ring buffer.
 *
 * This is not particularly efficient, but does the job for playd.
 * It uses two release-acquire-atomic counters to store read and write.
 */
class RingBuffer
{
public:
	/**
	 * Constructs a Ring_buffer.
	 * @param capacity The capacity of the ring buffer, in bytes.
	 */
	explicit RingBuffer(size_t capacity);

	/// Destructs a Ring_buffer.
	~RingBuffer() = default;

	/// Deleted copy constructor.
	RingBuffer(const RingBuffer &) = delete;

	/// Deleted copy-assignment.
	RingBuffer &operator=(const RingBuffer &) = delete;

	/**
	 * The current write capacity.
	 * @return The number of samples this ring buffer has space to store.
	 * @see Write
	 */
	size_t WriteCapacity() const;

	/**
	 * The current read capacity.
	 * @return The number of samples available in this ring buffer.
	 * @see Read
	 */
	size_t ReadCapacity() const;

	/**
	 * Writes samples from a span into the ring buffer.
	 *
	 * * Precondition: @a src is a valid span.
	 * * Postcondition: The ringbuffer has been written to with the contents
	 *     of the first WriteCapacity() bytes of @a src.
	 *
	 * @param src The span of bytes to write into the ring buffer.
	 * @return The number of bytes written.
	 * @see WriteCapacity
	 */
	size_t Write(gsl::span<const std::byte> src);

	/**
	 * Reads samples from the ring buffer into an array.
	 * To read one sample, pass a count of 1 and take a pointer to the
	 * sample variable.
	 *
	 * * Precondition: @a dest is a valid span.
	 * * Postcondition: The first ReadCapacity() bytes of @a dest have been
	 *     filled with the appropriate number of bytes from the front of the
	 *     ring buffer.
	 *
	 * @param dest The span of bytes to fill with bytes read from the ring
	 *  buffer.
	 * @return The number of bytes read.
	 * @see ReadCapacity
	 */
	size_t Read(gsl::span<std::byte> dest);

	/// Empties the ring buffer.
	void Flush();

private:
	/// Empties the ring buffer without acquiring locks.
	void FlushInner();

	std::vector<std::byte> buffer; ///< The array used by the ringbuffer.

	std::vector<std::byte>::const_iterator r_it; ///< The read iterator.
	std::vector<std::byte>::iterator w_it;       ///< The write iterator.

	std::atomic<size_t> count; ///< The current read capacity.
	// Write capacity is the total buffer capacity minus count.

	std::mutex r_lock; ///< The read lock.
	std::mutex w_lock; ///< The write lock.
};

} // namespace Playd::Audio

#endif // PLAYD_RINGBUFFER_HPP


#ifndef MODULE_WASM_TABLE_H
#define MODULE_WASM_TABLE_H

#include "function/TableFunction.h"
#include <gsl/span>

namespace wasm {

struct WasmTable {

	using wasm_external_kind_type = parse::Table;
	using any_function_type = std::optional<

	gsl::span<any_function_type> get_segment(std::size_t offset, std::size_t length)
	{
		assert(offset <= table_.size());
		assert((table_.size() - offset) >= lenfth);
		return gsl::span<TableFunction>(table_.data() + offset, length);
	}

	friend bool matches(const WasmTable& self, const parse::Table& tp)
	{
		return self.table_.size() >= tp.size() and (
			self.maximum_ == tp.maximum.value_or(std::numeric_limits<std::size_t>::max())
		);
	}

	const any_function_type& at(wasm_uint32_t idx) const
	{ return table_.at(idx); }

	any_function_type& at(wasm_uint32_t idx)
	{ return table_.at(idx); }

private:
	std::vector<table_function_type> table_;
	const std::size_t maximum_ = std::numeric_limits<std::size_t>::max();
};

} /* namespace wasm */

#endif /* MODULE_WASM_TABLE_H */


#pragma once
#include <string>
#include <type_traits>
#include <tuple>
#include <gsl.h>
#include "roster.h"
#include "timestamp.h"
#include <boost/multi_index/sequenced_index.hpp>

class Grade
{
public:
	class Key
	{
	private:
		Roster const& roster_;
		std::string grader_email_;
		std::string student_name_;

	private:
		friend bool operator==(const Key lhs, const Key rhs)
		{
			const auto result{ lhs.grader_email_ == rhs.grader_email_ && lhs.student_name_ == rhs.student_name_ };
			return result;
		}

	public:
		explicit Key(Roster const& roster);

		std::string getGraderEmail() const
		{
			Expects(!grader_email_.empty() && roster_.is_email_good(grader_email_));
			return grader_email_;
		}

		void setGraderEmail(const std::string grader_email)
		{
			Expects(!grader_email.empty() && roster_.is_email_good(grader_email));
			grader_email_ = grader_email;
		}

		std::string getStudentName() const
		{
			Expects(!student_name_.empty());
			return student_name_;
		}

		void setStudentName(const std::string student_name)
		{
			Expects(!student_name.empty());
			student_name_ = student_name;
		}

        bool is_good() const;
	};

private:
    Roster const& roster_;
	Key key_;
	Timestamp timestamp_{};
	unsigned score_{ 0 };

public:
	bool is_good() const;

	Key getKey() const
	{
		return key_;
	}

	Timestamp getTimestamp() const
	{
		return timestamp_;
	}

	unsigned getScore() const
	{
		return score_;
	}

private:
	void setTimestamp(const Timestamp timestamp)
	{
		Expects(timestamp.is_good());
		timestamp_ = timestamp;
	}

	friend std::istream& operator>>(std::istream& is, Grade& grade)
	{
		Timestamp timestamp;

		is >> timestamp;
		Ensures(timestamp.is_good());
		grade.setTimestamp(timestamp);

		char grader_email_cstr[256]{};
		constexpr auto max_grader_len{ std::extent<decltype(grader_email_cstr)>::value };
		is.getline(grader_email_cstr, max_grader_len, ',');
		auto const grader_len{ strlen(grader_email_cstr) };
		Ensures(grader_len > 0 && grader_len < max_grader_len);

		grade.key_.setGraderEmail(grader_email_cstr);

		is.ignore(std::numeric_limits<std::streamsize>::max(), ',');

		char student_name_cstr[256]{};
		constexpr auto max_student_name_len{ std::extent<decltype(student_name_cstr)>::value };
		is.getline(student_name_cstr, max_student_name_len, ',');
		auto const student_len{ strlen(student_name_cstr) };
		Ensures(student_len > 0 && student_len < max_student_name_len);

		grade.key_.setStudentName(student_name_cstr);

		Ensures(grade.is_good());

		is.seekg(-2, std::ios_base::end);

		auto const is_comma{ is.peek()==',' };

		if (is_comma)
		{
			is.ignore();
		}

		auto grade_value{ std::numeric_limits<int>::max() };

		is >> grade_value;

		Ensures(grade_value >= 0 && grade_value<(10+1) && is.eof());

		grade.score_ = 10 * grade_value;

		Ensures(grade.score_ >= 0 && grade.score_ < (100+1));

		return is;
	}

public:
	explicit Grade(Roster const& roster);
};