@@ -288,6 +288,87 @@ namespace alp {
288288 return rc;
289289 }
290290
291+ /* *
292+ * Sets the value of a given scalar \a alpha to be equal to that of
293+ * another given scalar \a beta.
294+ *
295+ * This operation is functionally equivalent to
296+ * \code
297+ * alp::operators::right_assign< T > op;
298+ * alp::foldl( alpha, beta, op );
299+ * \endcode,
300+ * \code
301+ * alp::operators::left_assign < T > op;
302+ * alp::foldr( beta, alpha, op );
303+ * \endcode, as well as the following pseudocode
304+ * \code
305+ * *alpha = *beta;
306+ * \endcode.
307+ *
308+ * The scalar \a alpha may not equal \a beta.
309+ *
310+ * \parblock
311+ * \par Accepted descriptors
312+ * -# alp::descriptors::no_operation
313+ * -# alp::descriptors::no_casting
314+ * \endparblock
315+ *
316+ * @tparam descr The descriptor of the operation.
317+ * @tparam OutputType The element type in the output scalar.
318+ * @tparam InputType The element type in the input scalar.
319+ * @tparam OutputStructure The structure of the ouput scalar.
320+ * @tparam InputStructure The structure of the input scalar.
321+ *
322+ * @param[in,out] alpha The scalar to be set.
323+ * @param[in] beta The source scalar.
324+ *
325+ * When \a descr includes alp::descriptors::no_casting and if \a InputType
326+ * does not match \a OutputType, the code shall not compile.
327+ *
328+ * \parblock
329+ * \par Performance semantics
330+ * A call to this function
331+ * -# consists of \f$ \Theta(1) \f$ work;
332+ * -# moves \f$ \Theta(1) \f$ bytes of memory;
333+ * -# does not allocate nor free any dynamic memory;
334+ * -# shall not make any system calls.
335+ * \endparblock
336+ *
337+ * @see alp::foldl.
338+ * @see alp::foldr.
339+ * @see alp::operators::left_assign.
340+ * @see alp::operators::right_assign.
341+ */
342+ template <
343+ Descriptor descr = descriptors::no_operation,
344+ typename OutputType, typename OutputStructure,
345+ typename InputType, typename InputStructure
346+ >
347+ RC set (
348+ Scalar< OutputType, OutputStructure, reference > &alpha,
349+ const Scalar< InputType, InputStructure, reference > &beta,
350+ const std::enable_if<
351+ !alp::is_object< InputType >::value &&
352+ !alp::is_object< OutputType >::value
353+ > * const = nullptr
354+ ) {
355+ // static sanity checks
356+ NO_CAST_ASSERT (
357+ ( !( descr & descriptors::no_casting ) || std::is_same< OutputType, InputType >::value ),
358+ " alp::set (scalar)" ,
359+ " called with a value type that does not match that of the given "
360+ " scalar"
361+ );
362+
363+ if ( !internal::getInitialized ( beta ) ) {
364+ internal::setInitialized ( alpha, false );
365+ return SUCCESS;
366+ }
367+
368+ // foldl requires left-hand side to be initialized prior to the call
369+ internal::setInitialized ( alpha, true );
370+ return foldl ( alpha, beta, alp::operators::right_assign< OutputType >() );
371+ }
291372 /* * @} */
292373
293374} // end namespace ``alp''
0 commit comments