1 //------------------------------------------------------------------------------
2 // GB_Scalar_extractElement_template: x = S
3 //------------------------------------------------------------------------------
4 
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7 
8 //------------------------------------------------------------------------------
9 
10 // Extract the value of single scalar, x = S, typecasting from the
11 // type of S to the type of x, as needed.
12 
13 // Returns GrB_SUCCESS if the GxB_Scalar entry is present, and sets x to its
14 // value.  Returns GrB_NO_VALUE if the GxB_Scalar is not present, and x is
15 // unmodified.
16 
17 // This template constructs GxB_Scalar_extractElement_[TYPE] for each of the
18 // 13 built-in types, and the _UDT method for all user-defined types.
19 
GB_EXTRACT_ELEMENT(GB_XTYPE * x,const GxB_Scalar S)20 GrB_Info GB_EXTRACT_ELEMENT     // extract a single entry from S
21 (
22     GB_XTYPE *x,                // scalar to extract, not modified if not found
23     const GxB_Scalar S          // GxB_Scalar to extract a scalar from
24 )
25 {
26 
27     //--------------------------------------------------------------------------
28     // check inputs
29     //--------------------------------------------------------------------------
30 
31     GB_RETURN_IF_NULL_OR_FAULTY (S) ;
32     GB_RETURN_IF_NULL (x) ;
33 
34     // delete any lingering zombies, assemble any pending tuples, and unjumble
35     if (GB_ANY_PENDING_WORK (S))
36     {
37         // extract scalar with pending tuples or zombies.  It cannot be
38         // actually jumbled, but S->jumbled might true anyway.
39         GrB_Info info ;
40         GB_WHERE1 (GB_WHERE_STRING) ;
41         GB_BURBLE_START ("GxB_Scalar_extractElement") ;
42         GB_OK (GB_Matrix_wait ((GrB_Matrix) S, "s", Context)) ;
43         GB_BURBLE_END ;
44     }
45 
46     ASSERT (!GB_ANY_PENDING_WORK (S)) ;
47 
48     // GB_XCODE and S must be compatible
49     GB_Type_code scode = S->type->code ;
50     if (!GB_code_compatible (GB_XCODE, scode))
51     {
52         return (GrB_DOMAIN_MISMATCH) ;
53     }
54 
55     if ((S->nzmax == 0)                         // empty
56         || (S->p != NULL && S->p [1] == 0)      // sparse/hyper with no entry
57         || (S->b != NULL && S->b [0] == 0))     // bitmap with no entry
58     {
59         // quick return
60         return (GrB_NO_VALUE) ;
61     }
62 
63     //--------------------------------------------------------------------------
64     // extract the scalar
65     //--------------------------------------------------------------------------
66 
67     #if !defined ( GB_UDT_EXTRACT )
68     if (GB_XCODE == scode)
69     {
70         // copy the value from S into x, no typecasting, for built-in
71         // types only.
72         GB_XTYPE *restrict Sx = ((GB_XTYPE *) (S->x)) ;
73         (*x) = Sx [0] ;
74     }
75     else
76     #endif
77     {
78         // typecast the value from S into x
79         GB_cast_array ((GB_void *) x, GB_XCODE,
80             ((GB_void *) S->x), scode, NULL, S->type->size, 1, 1) ;
81     }
82     return (GrB_SUCCESS) ;
83 }
84 
85 #undef GB_UDT_EXTRACT
86 #undef GB_EXTRACT_ELEMENT
87 #undef GB_XTYPE
88 #undef GB_XCODE
89 
90