예제 #1
0
inline ConstSubspecRef Spec::get_subtable_spec(size_t column_ndx) const noexcept
{
    REALM_ASSERT(column_ndx < get_column_count());
    REALM_ASSERT(get_column_type(column_ndx) == col_type_Table);
    size_t subspec_ndx = get_subspec_ndx(column_ndx);
    return ConstSubspecRef(&m_subspecs, subspec_ndx);
}
예제 #2
0
inline void Descriptor::insert_column_link(size_t col_ndx, DataType type, StringData name, Table& target,
                                           LinkType link_type)
{
    typedef _impl::TableFriend tf;

    if (REALM_UNLIKELY(!is_attached() || !target.is_attached()))
        throw LogicError(LogicError::detached_accessor);
    if (REALM_UNLIKELY(col_ndx > get_column_count()))
        throw LogicError(LogicError::column_index_out_of_range);
    if (REALM_UNLIKELY(!tf::is_link_type(ColumnType(type))))
        throw LogicError(LogicError::illegal_type);
    if (REALM_UNLIKELY(!is_root()))
        throw LogicError(LogicError::wrong_kind_of_descriptor);
    // Both origin and target must be group-level tables, and in the same group.
    Group* origin_group = tf::get_parent_group(*get_root_table());
    Group* target_group = tf::get_parent_group(target);
    if (!origin_group || !target_group)
        throw LogicError(LogicError::wrong_kind_of_table);
    if (origin_group != target_group)
        throw LogicError(LogicError::group_mismatch);

    LinkTargetInfo link(&target);
    tf::insert_column(*this, col_ndx, type, name, link); // Throws
    adj_insert_column(col_ndx);

    tf::set_link_type(*get_root_table(), col_ndx, link_type); // Throws
}
예제 #3
0
void run(unsigned int nbins, char * filename) {
	gsl_vector * min;
	gsl_vector * max;
	ndim_histogram * h;
	unsigned int ncolumns;

	debug("looking for number of columns ...");
	ncolumns = get_column_count(filename);
	dump_i("number of columns", ncolumns);
	min = gsl_vector_alloc(ncolumns);
	max = gsl_vector_alloc(ncolumns);

	debug("finding minima/maxima ...");
	dump_s("in file", filename);
	find_min_max(filename, min, max);
	dump_v("minima", min);
	dump_v("maxima", max);
	debug("creating histogram cube ...");
	h = ndim_histogram_alloc(nbins, min, max);

	debug("filling histogram ... ");
	append_to_hist(h, filename);

	output_hist(h);
	ndim_histogram_free(h);
}
예제 #4
0
static void load_data(mcmc * m, const char * filename) {
	FILE * input;
	int npoints = countlines(filename);
	int ndim = get_column_count(filename);
	gsl_matrix * data;
	IFDEBUGPARSER
	dump_i("lines", npoints);
	IFDEBUGPARSER
	dump_i("dimensions", ndim);

	data = gsl_matrix_alloc(npoints, ndim);

	input = openfile(filename);
	if (gsl_matrix_fscanf(input, data) != 0) {
		fprintf(stderr,
				"error reading input data. Perhaps inconsistent format?\n");
		fprintf(stderr, "tried to read %d x %d.\n", ndim, npoints);
		exit(3);
	}
	assert(fclose(input) == 0);

	m->data = data;

	IFDEBUGPARSER
	dump_i("loaded data points", npoints);
}
예제 #5
0
void command::retr_colinfo(ExceptionSink* xsink) {
   unsigned columns = get_column_count(xsink);
   if (xsink->isException()) return;
   colinfo.reset();
   get_row_description(colinfo.datafmt, columns, xsink);
   setup_output_buffers(colinfo.datafmt, xsink);
   colinfo.dirty = false;
}
예제 #6
0
const char * t_list_view::get_item_text(t_size index, t_size column)
{
	if (index >= m_items.get_count())
		return "";
	if (m_items[index]->m_subitems.get_count() != get_column_count())
		update_item_data(index);
	if (column >= m_items[index]->m_subitems.get_count())
		return "";
	return m_items[index]->m_subitems[column];
}
예제 #7
0
inline void Descriptor::rename_column(size_t col_ndx, StringData name)
{
    typedef _impl::TableFriend tf;

    if (REALM_UNLIKELY(!is_attached()))
        throw LogicError(LogicError::detached_accessor);
    if (REALM_UNLIKELY(col_ndx >= get_column_count()))
        throw LogicError(LogicError::column_index_out_of_range);

    tf::rename_column(*this, col_ndx, name); // Throws
}
예제 #8
0
inline void Spec::set_column_attr(size_t column_ndx, ColumnAttr attr)
{
    REALM_ASSERT(column_ndx < get_column_count());

    // At this point we only allow one attr at a time
    // so setting it will overwrite existing. In the future
    // we will allow combinations.
    m_attr.set(column_ndx, attr);

    update_has_strong_link_columns();
}
예제 #9
0
inline void Spec::set_column_type(size_t column_ndx, ColumnType type)
{
    REALM_ASSERT(column_ndx < get_column_count());

    // At this point we only support upgrading to string enum
    REALM_ASSERT(ColumnType(m_types.get(column_ndx)) == col_type_String);
    REALM_ASSERT(type == col_type_StringEnum);

    m_types.set(column_ndx, type); // Throws

    update_has_strong_link_columns();
}
예제 #10
0
inline void Descriptor::set_link_type(size_t col_ndx, LinkType link_type)
{
    typedef _impl::TableFriend tf;

    if (REALM_UNLIKELY(!is_attached()))
        throw LogicError(LogicError::detached_accessor);
    if (REALM_UNLIKELY(col_ndx >= get_column_count()))
        throw LogicError(LogicError::column_index_out_of_range);
    if (REALM_UNLIKELY(!tf::is_link_type(ColumnType(get_column_type(col_ndx)))))
        throw LogicError(LogicError::illegal_type);

    tf::set_link_type(*get_root_table(), col_ndx, link_type); // Throws
}
예제 #11
0
inline void Descriptor::insert_column(size_t col_ndx, DataType type, StringData name, DescriptorRef* subdesc,
                                      bool nullable)
{
    typedef _impl::TableFriend tf;

    if (REALM_UNLIKELY(!is_attached()))
        throw LogicError(LogicError::detached_accessor);
    if (REALM_UNLIKELY(col_ndx > get_column_count()))
        throw LogicError(LogicError::column_index_out_of_range);
    if (REALM_UNLIKELY(tf::is_link_type(ColumnType(type))))
        throw LogicError(LogicError::illegal_type);

    LinkTargetInfo invalid_link;
    tf::insert_column(*this, col_ndx, type, name, invalid_link, nullable); // Throws
    adj_insert_column(col_ndx);
    if (subdesc && type == type_Table)
        *subdesc = get_subdescriptor(col_ndx);
}
예제 #12
0
inline StringData Spec::get_column_name(size_t ndx) const noexcept
{
    REALM_ASSERT(ndx < get_column_count());
    return m_names.get(ndx);
}
예제 #13
0
inline ColumnType Spec::get_column_type(size_t ndx) const noexcept
{
    REALM_ASSERT(ndx < get_column_count());
    return ColumnType(m_types.get(ndx));
}
예제 #14
0
void t_list_view::__insert_items_v3(t_size index_start, t_size pcountitems, const t_item_insert * items)
{
	t_size l, countl = pcountitems;
	{
		pfc::list_t<t_item_ptr> itemsinsert;
		itemsinsert.set_count(countl);
		m_items.insert_items(itemsinsert, index_start);
	}

	if (m_highlight_selected_item_index != pfc_infinite && m_highlight_selected_item_index >= index_start) m_highlight_selected_item_index += countl;

	pfc::list_t<t_item_ptr> items_prev(m_items);
	t_size countitems = m_items.get_count();
	t_size newgroupcount = 0, oldgroupcount=0;

// Calculate old group count
	{
		t_size index = index_start + countl ;
		if (index < countitems)
		{
			t_size i, count = m_group_count;
			for (i=0; i<count; i++)
			{
				if ( (!index_start || m_items[index_start - 1]->m_groups[i] != m_items[index]->m_groups[i])
					)
					oldgroupcount++;
			}
		}
	}

// Determine grouping
	{
		t_item_ptr * p_items = m_items.get_ptr();
		for (l=0; l<countl; l++)
		{
			t_size i, count = m_group_count;
			t_size index = l + index_start;
			t_item * item;
			{
				item = storage_create_item();
				p_items[index] = item;
				item->m_subitems = items[l].m_subitems;
				item->m_display_index = index ? p_items[index-1]->m_display_index + 1 : 0;
				item->m_groups.set_size(count);
				if (m_variable_height_items) 
				{
					if (item->m_subitems.get_count() != get_column_count())
						update_item_data(index);
					item->update_line_count();
				}
			}
			bool b_new = false;

			bool b_left_same_above = true;
			bool b_right_same_above = true;
			for (i=0; i<count; i++)
			{
				bool b_left_same = false;
				bool b_right_same = false;
				if (!b_new && index)
				{
					b_left_same = b_left_same_above && !GROUP_STRING_COMPARE(items[l].m_groups[i], m_items[index-1]->m_groups[i]->m_text);
				}
				if (!b_new && index+1<countitems && l+1>=countl)
				{
					b_right_same = b_right_same_above && !GROUP_STRING_COMPARE(items[l].m_groups[i], m_items[index+1]->m_groups[i]->m_text);
				}
				if (b_new || (!b_left_same && !b_right_same))
				{
					item->m_groups[i] = storage_create_group();
					item->m_groups[i]->m_text = (items[l].m_groups[i]);
					b_new = true;
					item->m_display_index++;
				}
				if (b_left_same && b_right_same)
				{
					item->m_groups[i] = m_items[index-1]->m_groups[i];
					t_group_ptr test;
					{
						test = m_items[index+1]->m_groups[i];
						t_size j=index+1;
						while (j < countitems && test == m_items[j]->m_groups[i])
						{
							m_items[j]->m_groups[i] = item->m_groups[i];
							j++;
						}
					}
				}
				else if (b_left_same)
					item->m_groups[i] = m_items[index-1]->m_groups[i];
				else if (b_right_same)
				{
					item->m_display_index++;
					item->m_groups[i] = m_items[index+1]->m_groups[i];
				}
				b_right_same_above = b_right_same;
				b_left_same_above = b_left_same;

			}
		}

	}
	{
		t_size index = index_start + countl;
		if (index_start && index < countitems)
		{
			t_size index_prev = index_start - 1;
			t_size i, count = m_group_count;
			for (i=0; i<count; i++)
			{
				{
					if ( items_prev[index_prev]->m_groups[i] == items_prev[index]->m_groups[i])
					{
						if (m_items[index]->m_groups[i] != m_items[index-1]->m_groups[i])
						{
							t_group_ptr newgroup = storage_create_group();
							newgroup->m_text = (items_prev[index_prev]->m_groups[i]->m_text);
							t_size j = index;
							while (j < countitems && items_prev[index_prev]->m_groups[i] == items_prev[j]->m_groups[i])
							{
								m_items[j]->m_groups[i] = newgroup;
								j++;
							};
						}
					}
				}
			}
		}
	}

// Determine new group count
	{
		t_size countl2 = index_start + countl < countitems ? countl+1 : countl;
		for (l=0; l<countl2; l++)
		{
			t_size i, count = m_group_count;
			t_size index = l + index_start;
			for (i=0; i<count; i++)
			{
				if ( (!index || m_items[index-1]->m_groups[i] != m_items[index]->m_groups[i])
					)
					newgroupcount++;
			}
		}
	}

//Correct subsequent display indices
	{
		const t_size j_start = index_start+countl;
		t_size j = j_start;

		//console::formatter() << newgroupcount << " " << oldgroupcount;

		while (j < countitems)
		{
			m_items[j]->m_display_index += ((countl + newgroupcount-oldgroupcount));
			j++;
		}
	}
}
예제 #15
0
/*
 * get last 2 columns
 * must be called after the first temple building
 */
uint8_t strat_static_columns_pass2(void)
{
	uint16_t old_spdd, old_spda;
	uint8_t side, err, next_mode;

	DEBUG(E_USER_STRAT, "%s()", __FUNCTION__);

	strat_get_speed(&old_spdd, &old_spda);

	if (get_color() == I2C_COLOR_RED)
		side = I2C_RIGHT_SIDE;
	else
		side = I2C_LEFT_SIDE;

	if (strat_infos.conf.flags & STRAT_CONF_STORE_STATIC2)
		next_mode = I2C_MECHBOARD_MODE_STORE;
	else
		next_mode = I2C_MECHBOARD_MODE_HARVEST;

	switch (strat_infos.s_cols.configuration) {

	/* configuration 1: 4 cols on line 0 */
	case 1:
		if (strat_infos.s_cols.flags & STATIC_COL_LINE1_DONE) {
			/* go on line 2 */

			strat_set_speed(2000, 700);
			trajectory_d_a_rel(&mainboard.traj, -450, COLOR_A(35));
			err = wait_traj_end(TRAJ_FLAGS_NO_NEAR);
			if (!TRAJ_SUCCESS(err))
				ERROUT(err);
			
			i2c_mechboard_mode_prepare_pickup_next(side, 
							       next_mode);

			strat_set_speed(SPEED_DIST_SLOW, SPEED_ANGLE_FAST);
			trajectory_goto_forward_xy_abs(&mainboard.traj,
						       LINE2_X, 
						       COLOR_Y(400));
			err = WAIT_COND_OR_TRAJ_END(get_column_count() == 2,
						    TRAJ_FLAGS_NO_NEAR);
			if (!TRAJ_SUCCESS(err))
				ERROUT(err);
		}
		else {
			/* go on line 1 */
			strat_set_speed(2000, 700);
			trajectory_d_a_rel(&mainboard.traj, -650, COLOR_A(55));
			err = wait_traj_end(TRAJ_FLAGS_NO_NEAR);
			if (!TRAJ_SUCCESS(err))
				ERROUT(err);
			
			i2c_mechboard_mode_prepare_pickup_next(side, 
							       next_mode);

			strat_set_speed(SPEED_DIST_SLOW, SPEED_ANGLE_FAST);

			err = goto_and_avoid_forward(LINE1_X, 
						     COLOR_Y(400),
						     TRAJ_FLAGS_NO_NEAR,
						     TRAJ_FLAGS_NO_NEAR);
			if (!TRAJ_SUCCESS(err))
				ERROUT(err);
		}

		ERROUT(END_TRAJ);
		break;

	/* configuration 2: 2 cols on line 0,
	   all other colums are on line 1 */
	case 2:
		/* go on line 1 */
		strat_set_speed(2000, 700);
		trajectory_d_a_rel(&mainboard.traj, -410, COLOR_A(-20));
		err = wait_traj_end(TRAJ_FLAGS_NO_NEAR);
		if (!TRAJ_SUCCESS(err))
			ERROUT(err);
			
		i2c_mechboard_mode_prepare_pickup_next(side, 
						       next_mode);

		strat_set_speed(SPEED_DIST_SLOW, SPEED_ANGLE_FAST);

		err = goto_and_avoid_forward(COL10_X, COLOR_Y(400),
					     TRAJ_FLAGS_NO_NEAR,
					     TRAJ_FLAGS_NO_NEAR);
		if (!TRAJ_SUCCESS(err))
			ERROUT(err);
		
		ERROUT(END_TRAJ);
		break;

	/* configuration 3: 2 cols on line 0,
	   all other colums are on line 2 */
	case 3:
		/* go on line 2 */
		strat_set_speed(2000, 700);
		trajectory_d_a_rel(&mainboard.traj, -150, COLOR_A(-30));
		err = wait_traj_end(TRAJ_FLAGS_NO_NEAR);
		if (!TRAJ_SUCCESS(err))
			ERROUT(err);
			
		i2c_mechboard_mode_prepare_pickup_next(side, 
						       next_mode);

		strat_set_speed(SPEED_DIST_SLOW, SPEED_ANGLE_FAST);

		trajectory_goto_forward_xy_abs(&mainboard.traj,
					       LINE2_X, 
					       COLOR_Y(400));
		err = wait_traj_end(TRAJ_FLAGS_NO_NEAR);
		if (!TRAJ_SUCCESS(err))
			ERROUT(err);

		ERROUT(END_TRAJ);
		break;

	/* configuration 4: 2 cols on line 0,
	   2 on line 1, 2 on line 2 */
	case 4:
		/* go on line 1 */
		strat_set_speed(600, 2000);
		trajectory_d_a_rel(&mainboard.traj, -BIG_DIST,
				   COLOR_A(-135));
		err = WAIT_COND_OR_TRAJ_END(y_is_more_than(900),
					    TRAJ_FLAGS_STD);
		if (TRAJ_SUCCESS(err)) /* we should not reach end */
			ERROUT(END_ERROR);
		else if (err)
			ERROUT(err);

		DEBUG(E_USER_STRAT, "%s():%d", __FUNCTION__, __LINE__);
		i2c_mechboard_mode_prepare_pickup_next(side, 
						       next_mode);

		strat_set_speed(2000, 2000);
		trajectory_d_rel(&mainboard.traj, -BIG_DIST);
		err = WAIT_COND_OR_TRAJ_END(y_is_more_than(1100),
					    TRAJ_FLAGS_STD);
		if (TRAJ_SUCCESS(err)) /* we should not reach end */
			ERROUT(END_ERROR);
		else if (err)
			ERROUT(err);
		
		DEBUG(E_USER_STRAT, "%s():%d", __FUNCTION__, __LINE__);
		trajectory_d_a_rel(&mainboard.traj, -600, COLOR_A(40));
		err = wait_traj_end(TRAJ_FLAGS_NO_NEAR);
		if (!TRAJ_SUCCESS(err))
			ERROUT(err);
			
		DEBUG(E_USER_STRAT, "%s():%d", __FUNCTION__, __LINE__);
		strat_set_speed(SPEED_DIST_SLOW, SPEED_ANGLE_FAST);
		err = goto_and_avoid_forward(LINE1_X, 
					     COLOR_Y(400),
					     TRAJ_FLAGS_NO_NEAR,
					     TRAJ_FLAGS_NO_NEAR);
		ERROUT(END_TRAJ);
		break;

	default:
		break;
	}
	
	/* should not reach this point */
	ERROUT(END_ERROR);

 end:
	strat_set_speed(old_spdd, old_spda);
	return err;
}
예제 #16
0
/*
 * must be called from start area.
 * get 4 static columns and build a temple on the disc
 */
uint8_t strat_static_columns(uint8_t configuration)
{
	uint8_t err;
	uint8_t col1_present = 0, col4_present = 0;
	uint16_t old_spdd, old_spda;

	DEBUG(E_USER_STRAT, "%s(%d)", __FUNCTION__, configuration);

	strat_get_speed(&old_spdd, &old_spda);

	/* calibrate scanner */
	i2c_sensorboard_scanner_calib();

	i2c_mechboard_mode_harvest();

	/* go straight. total distance is less than 5 meters */
	strat_set_speed(1000, 1000);
	trajectory_d_rel(&mainboard.traj, BIG_DIST);

	/* when y > 50, break */
	err = WAIT_COND_OR_TRAJ_END(y_is_more_than(500), TRAJ_FLAGS_STD);
	if (TRAJ_SUCCESS(err)) /* we should not reach end */
		ERROUT(END_ERROR);
	else if (err)
		ERROUT(err);

	/* turn to 90° abs while going forward */
	DEBUG(E_USER_STRAT, "turn now");
	strat_set_speed(1000, 350);
	trajectory_only_a_abs(&mainboard.traj, COLOR_A(90));

	/* when y > 100, check the presence of column 4 */
	err = WAIT_COND_OR_TRAJ_END(y_is_more_than(1000), TRAJ_FLAGS_STD);
	if (TRAJ_SUCCESS(err)) /* we should not reach end */
		ERROUT(END_ERROR);
	else if (err)
		ERROUT(err);
	if (get_color() == I2C_COLOR_RED && sensor_get(S_COLUMN_RIGHT))
		col4_present = 1;
	if (get_color() == I2C_COLOR_GREEN && sensor_get(S_COLUMN_LEFT))
		col4_present = 1;

	/* when y > 120, check the presence of column 1 */
	err = WAIT_COND_OR_TRAJ_END(y_is_more_than(1200), TRAJ_FLAGS_STD);
	if (TRAJ_SUCCESS(err)) /* we should not reach end */
		ERROUT(END_ERROR);
	else if (err)
		ERROUT(err);
	if (get_color() == I2C_COLOR_RED && sensor_get(S_COLUMN_RIGHT))
		col1_present = 1;
	if (get_color() == I2C_COLOR_GREEN && sensor_get(S_COLUMN_LEFT))
		col1_present = 1;

	/* when y > 130, break */
	err = WAIT_COND_OR_TRAJ_END(y_is_more_than(1300), TRAJ_FLAGS_STD);
	if (TRAJ_SUCCESS(err)) /* we should not reach end */
		ERROUT(END_ERROR);
	else if (err)
		ERROUT(err);

	strat_infos.s_cols.flags |= STATIC_COL_LINE0_DONE;

	DEBUG(E_USER_STRAT, "col4=%d col1=%d", col4_present, col1_present);
	DEBUG(E_USER_STRAT, "have %d cols", get_column_count());

	if (configuration == 0) {
		if (get_column_count() > 2) {
			configuration = 1;
			if (col4_present || col1_present) {
				strat_infos.s_cols.flags |= 
					STATIC_COL_LINE2_DONE;
			}
			else {
				strat_infos.s_cols.flags |= 
					STATIC_COL_LINE1_DONE;
			}
		}

		/* only 2 colums on the first line */
		else {
			/* all other colums are on line 1 */
			if (col4_present && col1_present) {
				configuration = 2;
				strat_infos.s_cols.flags |= 
					STATIC_COL_LINE2_DONE;
			}

			/* only 2 columns on line 1, so there are also
			 * 2 on line 2 */
			else if (col4_present || col1_present) {
				configuration = 4;
				strat_infos.s_cols.flags |= 
					STATIC_COL_LINE2_DONE;
			}

			/* all other columns are on line 2 */
			else {
				configuration = 3;
				strat_infos.s_cols.flags |= 
					STATIC_COL_LINE1_DONE;
			}
		}
	}

	strat_infos.s_cols.configuration = configuration;
	DEBUG(E_USER_STRAT, "use configuration %d", configuration);

	if (configuration == 1) {
		/* we already got 4 columns, go to the disc directly */

		strat_set_speed(1500, 900);
		trajectory_only_a_abs(&mainboard.traj, COLOR_A(0));
		err = WAIT_COND_OR_TRAJ_END(x_is_more_than(1100), TRAJ_FLAGS_STD);

		if (TRAJ_SUCCESS(err)) /* we should not reach end */
			ERROUT(END_ERROR);
		else if (err)
			ERROUT(err);
	}
	else if (configuration == 2 /* go from line 0 to line 1 */) {
		strat_set_speed(800, 1000);
		/* relative is needed here */
		trajectory_only_a_rel(&mainboard.traj, COLOR_A(-180));
		err = WAIT_COND_OR_TRAJ_END(!y_is_more_than(1300), TRAJ_FLAGS_STD);
		if (TRAJ_SUCCESS(err)) /* we should not reach end */
			ERROUT(END_ERROR);
		else if (err)
			ERROUT(err);
		strat_set_speed(1000, 600);
		err = WAIT_COND_OR_TRAJ_END(!y_is_more_than(1100),
					    TRAJ_FLAGS_STD);
		if (TRAJ_SUCCESS(err)) /* we should not reach end */
			ERROUT(END_ERROR);
		else if (err)
			ERROUT(err);
	}
	else if (configuration == 3 /* go from line 0 to line 2 and there is 4 columns
		    on line 2*/) {
		strat_set_speed(1000, 600);
		/* relative is needed here */
		trajectory_only_a_rel(&mainboard.traj, COLOR_A(-180));
		err = WAIT_COND_OR_TRAJ_END(!y_is_more_than(1110), TRAJ_FLAGS_STD);
		if (TRAJ_SUCCESS(err)) /* we should not reach end */
			ERROUT(END_ERROR);
		else if (err)
			ERROUT(err);
	} 	
	else if (configuration == 4 /* go from line 0 to line 2 and there is 2 columns
		      on line 2 */) {
		strat_set_speed(1000, 600);
		/* relative is needed here */
		trajectory_only_a_rel(&mainboard.traj, COLOR_A(-180));
		err = WAIT_COND_OR_TRAJ_END(!y_is_more_than(600), TRAJ_FLAGS_STD);
		if (TRAJ_SUCCESS(err)) /* we should not reach end */
			ERROUT(END_ERROR);
		else if (err)
			ERROUT(err);
	}
	else {
		trajectory_stop(&mainboard.traj);
	}

	ERROUT(END_TRAJ);

 end:
	strat_set_speed(old_spdd, old_spda);
	return err;
}
예제 #17
0
inline ColumnAttr Spec::get_column_attr(size_t ndx) const noexcept
{
    REALM_ASSERT(ndx < get_column_count());
    return ColumnAttr(m_attr.get(ndx));
}